cf链接http://codeforces.com/contest/542/problem/C
一开始题意理解错了,错题意写出的代码都能过好多点真是醉了,还以为代码写挫了,后来又仔细回去看了看题,才真正理解
了题意,幂等幂等,就是a^x=a,或者
问题可以转化为,在那些点上建边,一个幂等就是进入的环的长度,要满足所有都幂等就是所有的环的长度的最小公倍数,
但是有一点需要注意,如果一开始一个点没有在环上,且它到环上的距离大于最终的最小公倍数,此时答案应该一直+ans,
直到大于最大的步数,如图
图一,所有点的环最小公倍数是2,1到环的步数是1(<2)所以最终答案就是2
图二,每个点都直接在环上,环的长度都是3,所以最终答案就是3
图三,所有点的环都是2,最终最小公倍数是2,但是1到环的步数是3(>2),所以答案是4(2+2)。
代码如下,改编自cf大佬
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
int f[205],n,m,l[205],u[205];
ll a = 1;
ll lcm(ll a, ll b){
return a / __gcd(a,b)*b;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&f[i]);
for(int i=1;i<=n;i++)
{
memset(u,0,sizeof(u));
int t=i,c=0;
while(!u[t])
{
l[t]=c++;
u[t]=true;
t=f[t];
}
//printf("c=%d t=%d l[%d]=%d\n",c,t,t,l[t]); cout<<c-l[t]<<endl;
a = lcm(a,(c-l[t]*1ll));
m=max(m,l[t]);
} //cout<<endl;
ll t = a;
while(a < m){
a += t;
}
printf("%lld\n",a);
return 0;
}