欧拉函数线性筛法
首先我们知道欧拉函数是1到n-1中与n互质的数的个数。
除此之外,我们还要知道一些性质:
当p是素数时
1. phi(p)=p-1。(不多bb)
2. phi(p^k)=(p-1)*p^(k-1)
证明:
令n == p^k,小于 n 的正整数共有 p^k-1 个,其中与 p 不互素的个数共 p^(k-1)-1 个,它们是 1*p,2*p,3*p ... (p^(k-1)-1)*p
所以phi(p^k) == (p^k-1) - (p^(k-1)-1) == p^k - p^(k-1) == (p-1) * p^(k-1)。
3. 如果i%p==0,那么phi(i*p)=p*phi(i);(自行理解)
4. 如果i%p!=0,那么phi(i*p)=(p-1)*phi(i);
证明:
因为欧拉函数是积性函数,所以有phi(i*p)=phi(i)*phi(p),然后p是素数,所以phi(i*p)=(p-1)*phi(i);
知道了上面的四个性质,相信大家就可以写出线性筛法求欧拉函数的代码了.
我用的是欧拉筛法的同时筛出欧拉数(啦啦啦):
int prime[1000045],cnt; int phi[1000045]; bool vis[1000045]; il void shai() { for(int i=2;i<=1000045;i++) { if(!vis[i])//su shu { prime[++cnt]=i; phi[i]=i-1;//xing zhi 1 } for(int j=1;j<=cnt;j++) { if(i*prime[j]>100000) break; vis[i*prime[j]]=1; if(i%prime[j]==0) { phi[i*prime[j]]=prime[j]*phi[i];//xing zhi 3 break; } else phi[i*prime[j]]=(prime[j]-1)*phi[i];//xing zhi 4 } } }
PEACE