定义:
φ(x):在小于x的正整数中,与x互质的数字的个数。
计算:
φ(x)=x*(1-1/p1) * (1-1/p2) *(1-1/p3) *…,其中p1,p2,p3…是x的质因子。
性质:
1. 当n与m互质,则φ(nm)=φ(n)*φ(m)
2. 当n%m=0,则φ(nm)=φ(n)*m
3. 当n%2=1,则φ(2n)=φ(n)
4. 小于x且与x互质的那些数的和为 φ(x)*x/2
证明:
因为:gcd(a,x)=1则gcd(x-a,x)=1。【a<x】
所以:若a与x互质,那么必存在x-a与x也互质,那么就是说在[1,x-1]中,那φ(x)个与x互质的数中,每两个就可以凑一个x【a+(x-a)=x】
5. x%m=0&&(x/m)%m = 0:φ(x)=φ(x/m)*m
证明:
x%m=0则x=c *m
(x/m)%m=c%m=0则c=t *m
那么,x=c * t * m2,令k=c *t,则 x=k *m2
φ(x)=φ(k *m *m)=φ(k *m) *m【利用 #2】
则:φ(x)=φ(x/m) *m
6. x%m=0&&(x/m)%m != 0:φ(x)=φ(x/m)*(m-1)
这个不会证
代码:求phi[i]
用定义公式求数n的欧拉【一个】:
ll eular(ll n){
ll ans = n;
for(int i=2;i*i<=n;i++){
if(n%i == 0){
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
}
if(n>1)ans=ans/n*(n-1);
return ans;
}
求一堆:
void euler(){
for(int i=2;i<maxn;i++){
if(!E[i])
for(int j=i;j<maxn;j+=i){
if(!E[j])E[j]=j;
E[j]=E[j]/i*(i-1);
}
}
}
筛素数的时候求:
void get_phi(){
int i,j,k;
k=0;
for(i=2;i<maxn;i++){
if(is_prime[i]==false){
prime[k++]=i;
phi[i]=i-1;
}
for(j=0;j<k&&i*prime[j]<maxn;j++){
is_prime[i*prime[j]]=true;
if(i%prime[j] == 0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
欧拉定理:当x与p互质时,xφ(p)%p 恒等于1:xφ(p)=1(mod p)
降幂公式:
-
当gcd(x,p)=1
x t %p=x t%φ(p)%p, -
当t<φ(p)且gcd(x,p)!=1
x t %p=x t %p, -
当t>=φ(p)且gcd(x,p)!=1。
x t %p=x t%φ(p)+φ(p)% p,
看的是底数和模数的关系,不是幂次数与模数的关系!
求幂的话可用快速幂,求an%mod:
int qpow(int a,int n,int mod){
int ans=1;
while(n){
if(n&1)ans=(ll)ans*a%mod;
a=(ll)a*a%mod;
n=n/2;
}
return ans;
}
关于%的运算
- (a+b)%m=(a%m+b%m)%m
- (a-b)%m=(a%m-b%m+m)%m
- (a * b)%m=(a%m) * (b%m)%m
- 除法就需要用逆元了
- ab%m=((a%m)b)%m
- k*a%(k *p)=k *(a%p)