ACM数论基础

欧几里得:

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 }

扩展欧几里得:

    乘法逆元:如果有ax1mop),则称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),这三项是不是完美解决了,,嗯,快速幂就是这样。

费马小定理:

   即费马小定理。
  容易知:逆元即为 x^(p-2);
 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 }

莫比乌斯变换:

  暂时不懂。。。。。

猜你喜欢

转载自www.cnblogs.com/dahaihaohan/p/9325802.html