【板子】数论集合

快速幂

 1 LL pow_mod(LL a,LL b,LL p){
 2     LL res = 1;
 3     while(b){
 4         if( b & 1){            //(b%2==1)
 5             res = (res * a) % p;
 6         }
 7         a = (a * a) % p;
 8         b >>= 1;
 9     }
10     return res;    
11 } //合并再做乘法、 a ^ b % p 

 

 

GCD

1 int gcd(int a, int b){
2     if(b == 0){
3         return a;
4     }
5     return gcd(b,a%b);
6     
7 }

顺带一提。。a * b == gcd(a,b) * lcm(a,b);

 

EXGCD

求x,y,使得gcd(a,b) = a*x +b*y = d

int exgcd(int a,int b,int &x,int &y){
    if(b == 0){
        x = 1; y = 0;
        return a;
    }
    int d = exgcd(b,a%b,x,y);
    int t = x;
    x = y;
    y = t - a / b * y;
    return d;
}

 

中国剩余定理

a = b[i] % w[i]  这里w[]之间两两互质。求a。

 1  int China(int b[],int w[], int len){
 2     int n = 1,a = 0;
 3     int d,x,y,m;
 4     
 5     for(int i = 0 ; i < len ;i++){
 6         n *= w[i];
 7     }
 8     for(int i = 0; i < len ;i++){
 9         m = n / w[i];
10         d = exgcd(w[i], m,x,y);
11         a = (a + y * m * b[i]) % n;
12     }
13     if(a > 0)    return a;
14     else    return (a + n); 
15 }

 

欧拉函数

 1 const int N = 1e6 + 10; 
 2 int phi[N],prime[N];
 3 int tot;    //表示prime[]中有多少素数 
 4 void Euler(){
 5     phi[1] = 1;
 6     for(int i = 2; i < N; i++){
 7         if(!phi[i]){
 8             phi[i] = i-1;
 9             prime[tot++] = i;
10         }
11         for(int j = 0; j < tot && 1ll * i * prime[j] < N; j++){
12             if(i % prime[j])
13                 phi[i * prime[j]] = phi[i] * (prime[j]-1);
14             else{
15                 phi[i * prime[j] ] = phi[i] * prime[j];
16                 break;
17             }
18         }
19     }
20 } 

 

组合数

 1 //组合数C(n,m)
 2 const int mod = 1e9+7;
 3 int F[N],Finv[N],inv[N];
 4 void init(){
 5     inv[1] = 1;
 6     for(int i = 0 ; i < N; i++){
 7         inv[i] = (mod - mod/i)*1ll*inv[mod % i] % mod;
 8     }
 9     F[0] = Finv[0] = 1;
10     for(int i = 1; i < N; i++){
11         F[i] = F[i-1] * 1ll * i % mod;
12         Finv[i] = Finv[i-1] * 1ll * inv[i] % mod;
13     }
14 }
15 int cmob(int n ,int m){
16     if(m < 0 || m > n){
17         return 0;
18     }
19     return F[n] * 1ll * Finv[n-m] % mod * Finv[m] % mod;
20 }
21 //大组合数Lucas
22 ll Lucas( ll n ,ll m,int p){
23     if(m){
24         return Lucas(n / p, m / p,  p) * comb(n % p, m % p, p) % p;
25     }
26     else    return 1;
27 } 

 

O1快速乘

 

1 ll multi(ll x,ll y,ll mod){
2     ll tmp = (x * y - (ll)((long double) x / mod * y + 1.0e-8) * mod);
3     return tmp < 0 ? tmp+mod : tmp;
4 }

 

posted @ 2018-05-22 22:02  甜酒果。  阅读(300)  评论(2编辑  收藏  举报