题目大意思:
给定一个数的next值,问最小的k值,使得每次进行k次操作得到的数都是一样的。
将每个位置i记为点i
记circle[i]为从i出发出现环的环内元素,我们的任务就是求这些数的最小公倍数lcm,还要考虑‘6’型循环的情况,这个我们只需要求最大的多余长度之后对lcm向上取整就好了
#include<cstdio> #include<stack> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int maxn = 205; int next[maxn],vis[maxn]; LL circle[maxn],maxv = 0; LL gcd(LL a,LL b){ return b == 0 ? a : gcd(b,a % b); } int main(){ int n; scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&next[i]); for(int i = 1; i <= n; i++){ stack<int>Stack; memset(vis,0,sizeof(vis)); int pos = i; circle[i] = 0LL; while(!vis[pos]){ vis[pos] = 1; Stack.push(pos); pos = next[pos]; } while(true){ int e = Stack.top(); Stack.pop(); circle[i] ++; if(e == pos) break; } maxv = max(maxv,(LL)Stack.size()); } LL lcm = circle[1]; for(int i = 2; i <= n; i++){ lcm = lcm / gcd(lcm,circle[i]) * circle[i]; } LL temp = maxv / lcm; if(maxv % lcm || maxv == 0) temp ++; LL ans = temp * lcm; printf("%lld\n",ans); return 0; }
时间: 2024-10-24 14:27:46