?
大致题意:由n个珠子,n种颜色,组成一个项链。要求不同的项链数目,旋转后一样的属于同一种,结果模p。
?
n个珠子应该有n种旋转置换,每种置换的循环个数为gcd(i,n)。如果直接枚举i,显然不行。但是我们可以缩小枚举的数目。改为枚举每个循环节的长度L,那么相应的循环节数是n/L。所以我们只需求出每个L有多少个i满足gcd(i,n)= n/L,就得到了循环节数为n/L的个数。重点就是求出这样的i的个数。
?
令cnt = gcd(i,n) = n/L;
那么cnt | i,令i = cnt*t(0 <= t <= L);
又 n = cnt * L ;
所以gcd(i,n) = gcd( cnt*t, cnt*L) = cnt,
满足上式的条件是 gcd(t,L) = 1。
而这样的t 有Eular(L)个。
因此循环节个数是n/L的置换个数有Eular(L)个。
参考博客:http://blog.csdn.net/tsaid/article/details/7366708
?
代码中求欧拉函数是基于素数筛的,素数只需筛到sqrt(1e9)即可。我在筛素数的同时递推的记录了sqrt(1e9)以内的Eular(n),用phi[]表示。这样会快那么一点点。
?
?
#include
#include
#include
#include
#include
?