欧几里得:
1 int gcd(int a,int b){ 2 while(b){ 3 int t=a%b; 4 a=b; 5 b=t; 6 } 7 return a; 8 }
扩展欧几里得:
乘法逆元:如果有ax≡1( mod p),则称x是mod p意义下a的乘法逆元。
逆元:x是最小的正整数解;
1 int e(int a,int b,int &x,int &y){ 2 if(b!=0){ 3 x=1; 4 y=0; 5 return a; 6 } 7 int ans=e(b,a%b,x,y) 8 int temp=x; 9 x=y; 10 y=temp-(a/b)*x; 11 return ans; 12 } //ans是最大公约数,x是逆元;
欧拉函数:
Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。euler(1)=1(唯一和1互质的数就是1本身)。
欧拉公式的延伸:一个数的所有质因子之和是euler(n)*n/2。
1 int Euler(int n){ 2 int ret=n; 3 for(int i=2;i<=sqrt(n);i++) 4 if(n%i==0){ 5 ret=ret/i*(i-1);//先进行除法防止溢出(ret=ret*(1-1/p(i))) 6 while(n%i==0) 7 n/=i; 8 } 9 if(n>1) 10 ret=ret/n*(n-1); 11 return ret; 12 }
中国剩余定理:
设正整数两两互素,则同余方程组
有整数解。并且在模下的解是唯一的,解为
其中,而为模的逆元。
1 int shengyu(int a[],int m[],int n) { 2 int M = 1; 3 int ans = 0; 4 for(int i=1; i<=n; i++) 5 M*=m[i]; 6 for(int i=1; i<=n; i++) { 7 int x,y; 8 int Mi=M/m[i]; 9 e(Mi,m[i],x,y); //扩展欧几里得 10 ans=(ans+Mi*x*a[i])%M; 11 } 12 if(ans<0) ans+=M; 13 return ans; 14 }
快速幂:
1 int poww(int a,int b){ 2 int ans=1,base=a; 3 while(b!=0){ 4 if(b&1!=0) 5 ans*=base; 6 base*=base; 7 b>>=1; 8 } 9 return ans; 10 }
以b==11为例,b=>1011,二进制从右向左算,但乘出来的顺序是 a^(2^0) * a^(2^1) * a^(2^3),是从左向右的。我们不断的让base*=base目的即是累乘,以便随时对ans做出贡献。
其中要理解base*=base这一步,看:::base*base==base^2,下一步再乘,就是base^2*base^2==base^4,然后同理 base^4 * base4 = base^8 ,,,,, see?是不是做到了base-- >base^2-->base^4-->base^8-->base^16-->base^32.......指数正是 2^i 啊,再看上面的例子,a¹¹ = a^(2^0) * a^(2^1) * a^(2^3),这三项是不是完美解决了,,嗯,快速幂就是这样。
费马小定理:
1 long long qmod(long long a, long long b, long long p) { 2 long long ans= 1; 3 long long base= a%p; 4 while(b) { 5 if(b&1) 6 ans=(ans*base)%p; 7 base=(base*base)%p; 8 b>>= 1; 9 } 10 return ans; 11 }
莫比乌斯变换:
暂时不懂。。。。。