zoukankan      html  css  js  c++  java
  • 数论模板

    #### 1.GCD
    
    ```C++
    ll GCD(ll a,ll b) { return b?GCD(b,a%b):a ;}
    ```
    
    #### 2.快速GCD(Extend great common divisor)
    
    ```C++
    ll QGCD(ll l,ll r,ll &x,ll &y)
    {
        if(!r)
        {
            x=1;y=0;
            return l;
        }
        else
        {
            ll ans = QGCD(r,l%r,y,x);
            y -= l/r*x;
            return ans;
        }
    }
    ll kgcd(ll a, ll b)
    {
        if (a == 0)
            return b;
        if (b == 0)
            return a;
        if (!(a & 1) && !(b & 1))
            return kgcd(a>>1, b>>1)<<1;
        else if (!(b & 1))
            return kgcd(a, b>>1);
        else if (!(a & 1))
            return kgcd(a>>1, b);
        else
            return kgcd(abs(a - b), min(a, b));
    }
    ```
    
    #### 3.求a关于m的乘法逆元
    
    ```c++
    ll QGCD(ll l,ll r,ll &x,ll &y)
    {
        if(!r)
        {
            x=1;y=0;
            return l;
        }
        else
        {
            ll ans = QGCD(r,l%r,y,x);
            y -= l/r*x;
            return ans;
        }
    }
    ll mod_inverse(ll a,ll m)
    {
        if(QGCD(a,m,x,y)==1) //ax + my = 1
            return (x%m+m)%m;
        return -1;
    }
    
    //求逆元:ans = a/b mod m = (a mod (m*b) )/b
    ```
    
    #### 4.快速幂
    
    ```C++
    ll qpow(ll a,ll b,ll m)
    {
        ll ans = 1 ;
        while(b)
        {
            if(b&1)
                ans = ans*a%m;
            a*=a;
            b>>=1;
        }
        return ans;
    }
    ```
    
    #### 5.快速乘(二分乘法)
    
    ```C++
    ll qmul(ll a,ll b,ll m)
    {
        ll ans = 0 , ch = 1;
        if(a<0) ch = -1,a = -a;
        if(b<0) ch *= -1,b = -b;
        while(b)
        {
            if(b&1)
                ans = (ans+a)%m;
            a=(a*2)%m;
            b>>=1;
        }
        return ans*ch;
    }
    ```
    
    #### 6.中国剩余定理(col = a[i] % m[i] )
    
    ```C++
    ll QGCD(ll l,ll r,ll &x,ll &y)
    {
        if(!r)
        {
            x=1;y=0;
            return l;
        }
        else
        {
            ll ans = QGCD(r,l%r,y,x);
            y -= l/r*x;
            return ans;
        }
    }
    ll china(ll n,ll *a,ll *m)
    {
        ll ans = 1 , col = 0 , y , x ;
        for(int i=1;i<=n;i++)
            ans *= m[i];
        for(int i=1;i<=n;i++)
        {
            cnt = ans/m[i];
            QGCD(m[i],cnt,x,y) ; //m[i]*x+cnt*y = 1;
            col = (col + y*cnt*a[i])%ans;
        }
        return (col+ans)%ans;
    }
    ```
    
    #### 7.筛选素数
    
    ```C++
    int prime[mxn],vis[mxn];
    void Isprime()
    {
        mem(vis,1);
        int index = 0 ;
        for(int i=2;i<n;i++)
        {
            if(vis[i])
            {
                prime[index++] = i;
                for(int j=i+i;j<n;j+=i)
                    vis[j] = false;
            }
        }
    }
    ```
    
    #### 8.快速计算逆元
    
    ```c++
    void inverse()
    {
        inv[1] = 1;
        for(int i=2;i<n;i++)
        {
            if(i>=m) break;
            inv[i] = (m-m/i)*inv[m%i]%m;
        }
    }
    ```
    
    #### 9.组合数取模
    
    ```C++
    //1<= n , m <=1e5,预处理逆元和阶乘
    ll fac[n] = {1,1},inv[n] = {1,1} , f[n] = {1,1};
    ll check(ll a ,ll b)
    {
        return b>a? 0 : fac[a]*inv[b]%m*inv[a-b]%m;
    }
    void init()
    {
        for(int i=2;i<n;i++)
        {
            fac[i] = fac[i-1]*i%m;
            f[i] = (m-m/i)*f[m%i]%m;
            inv[i] = inv[i-1]*f[i]%m;
        }
    }
    //1<=m<=1e5 , n<1e9
    ll check(ll n,ll m )
    {
        if(m>n) return 0;
        ll ans =1;
        for(int i=1;i<=m;i++)
            ans = ans*(n-i+1)%m*qpow(i,m-2,m)%m;
        return ans;
    }
    
    
    ```
    
    #### 10,lucas大组合取模
    
    ```C++
    //m,m<=1e18 , p<1e5 
    #define N 100005
    #define M 100007
    ll n,m,fac[N]={1};
    ll C(ll n,ll m){
        if(m>n)return 0;
        return fac[n]*qpow(fac[m],M-2,M)%M*qpow(fac[n-m],M-2,M)%M;//费马小定理求逆元
    }
    ll lucas(ll n,ll m){
        if(!m)return 1;
        return(C(n%M,m%M)*lucas(n/M,m/M))%M;
    }
    void init(){
        for(int i=1;i<=M;i++)
            fac[i]=fac[i-1]*i%M;
    }
    
    ```
    所遇皆星河
  • 相关阅读:
    为什么需要多重继承?它的优缺点是什么?
    delete
    链表环状检测主要有三种方法
    常见和链表相关的算法
    二分查找算法
    找出两个字符串中最长的相同子字符串
    链表创建打印删除
    python项目
    hadoop博客 oschina
    用shell写个100以内的所有数字之和
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/11795812.html
Copyright © 2011-2022 走看看