欧拉函数 Euler :phi[n]= 1~n中所有与他互质的数的个数
- 先分解质因数 欧拉函数公式:
//欧拉函数 #include<iostream> #include<algorithm> using namespace std; int main() { int n; cin>>n; while(n--) { int a; cin>>a; int res =a; for(int i=2;i<=a/i;i++) if(a%i==0) { res=res/i*(i-1); while(a%i==0) a/=i; } if(a>1) res = res/a*(a-1); cout<<res<<endl; } return 0; }
筛法求1~n中所有数欧拉函数的总和(结合线性筛法求质数)
- 质数欧拉函数的 euler[p]=p-1;
- 非质数: if(i%primes[j]) euler[i*primes[j]]= primes[j] * euler[i]; else euler[i*primes[j]]= (primes[j]-1)*euler[i];
LL get_eulers(int n) { for(int i=2;i<=n;i++) { if(!st[i]) primes[cnt++]=i;phi[i]=i-1; for(int j=0;primes[j]<=n/i;j++) { st[primes[j]*i]=true; if(i%primes[j]) phi[i*primes[j]]=primes[j]*phi[i];break; phi[i*primes[j]]=(primes[j]-1)*ph[i]; } LL res = 0; for(int i=0;i<=n;i++) res+=phi[i]; return res; }
快速幂
- 任何一个数都可以写成几个2^n 相加的形式,因为每个数都有二进制表示
//a^k%q int qmi(int a,int k,int q) { int res =1; while(k) { if(k&1) res=(LL)res*a%q; k>>=1; a=(LL)a*a%q; } return res; }
快速幂求逆元: 条件 b和p互质
扩展欧几里得算法:(已知a,b;求满足的任意x,y)
//扩展欧几里得 int ex_gcd(int a,int b,int &x,int &y) { if(!b) { x =1,y=0; return a; }else { int d= ex_gcd(b,a%b,y,x); y-=a/b*x; return d; } }