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

    1.exgcd

    #define ll long long
    
    void exgcd(ll a,ll b)
    {
        if(b==0)
        {
            x=1,y=0;gcd=a;
            return;
        }exgcd(b,a%b);
        ll tmp=x,x=y,y=tmp-a/b*y;
    }
    View Code

     2.素数

    #define N 1000007
    
    void prime()
    {
        for(int i=2;i<=N;i++)
        {
            if(!no[i]) prime[++tot]=i;
            for(int j=1;j<=tot;j++)
            {
                if(i*prime[j]>=N)break;
                no[i*prime[j]]=1;
                if(i%prime[j]==0) break;
            }
        }
    }
    欧拉筛
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<ctime>
    #include<cstdlib>
    
    #define ll long long
    #define N 100010
    
    using namespace std;
    ll p,a;
    
    ll kfc(ll a,ll b)
    {
        ll res=0;
        a%=p;b%=p;
        while(b)
        {
            if(b&1) b--,res+=a,res%=p;
            a<<=1,a%=p,b>>=1;
        }return res%p;
    }
    
    ll ksm(ll a,ll b)
    {
        ll res=1;
        while(b)
        {
            if(b&1) res=kfc(res,a)%p;
            b>>=1; a=kfc(a,a)%p;
        }return res;
    }
    
    int main()
    {
        srand(time(0));
        cin>>p;
        for(ll i=1;i<=15;i++)
        {
            a=rand()%(p-1)+1;
            ll x=ksm(a,p-1);
            if(x!=1)
            {
                printf("NO
    ");
                return 0;
            }
        }
        printf("Yes
    ");
        return 0;
    }
    费马小定理判素数(快速幂 快速乘)

     3.质因数分解

    3.
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n;
    int a[10000];
    
    int main()
    {
        scanf("%d",&n);
        printf("%d=",n);
        int cnt=0;
        for (int i=2;i<=n;i++)
        {
            while (n%i==0&&n)
            {
                a[cnt++]=i;
                n/=i;
            }
        }
        for (int i=0;i<cnt-1;i++)
        {
            printf("%d*",a[i]);
        }
        printf("%d
    ",a[cnt-1]);
        return 0;
    } 
    
    分解单个数
    单个数
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 100010
    
    using namespace std;
    int no[N],prime[N],cnt[N];
    int tot,n;
    
    void is_prime()
    {
        for(int i=2;i<=N;i++)
        {
            if(!no[i]) prime[++tot]=i;
            for(int j=1;j<=tot;j++)
            {
                if(i*prime[j]>=N) break;
                no[i*prime[j]]=1;
                if(i%prime[j]==0) break;
            }
        }
    }
    
    int main()
    {
        is_prime();int x=1;
        scanf("%d",&n);tot=0;
        for(int i=1;i<=n;i++)
        {
            x=1;
            tot++;int P=prime[i];
            while(x)
            {
                x=n/P;
                cnt[tot]+=x;
                P*=prime[i];
            }
        }
        for(int i=1;i<=tot;i++) if(cnt[i]!=0)printf("%d ",cnt[i]);
        return 0;
    }
    阶乘

    4.卡特兰数

    1.f(n)=f(n-1)*(4*n-2)/(n+1)

    2.h(0)=0,h(1)=1

    h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n>=2)

    #include <iostream>
    #include <stdio.h>
    #include <cmath>
    using namespace std;
    
    int a[105][105];    //
    int b[105];       
    
    void catalan()  
    {
        int i,j,len,carry,temp;
        a[1][0]=b[1]=1;
        len=1;
        for(i=2;i<=100;i++)
        {
            for(j=0;j<len;j++)   
                a[i][j]=a[i-1][j]*(4*(i-1)+2);
            carry=0;
            for(j=0;j<len;j++)    
            {
                temp=a[i][j]+carry;
                a[i][j]=temp%10;
                carry=temp/10;
            }
            while(carry)    
            {
                a[i][len++]=carry%10;
                carry/=10;
            }
            carry=0;
            for(j=len-1;j>=0;j--) 
            {
                temp=carry*10+a[i][j];
                a[i][j]=temp/(i+1);
                carry=temp%(i+1);
            }
            while(!a[i][len-1])    
                len--;
            b[i]=len;
        }
    }
    
    int main()
    {
        int i,n;
        catalan();
        scanf("%d",&n);
        for(i=b[n]-1;i>=0;i--)
          printf("%d",a[n][i]);
        return 0;
    }
    高精度

    5.逆元

    /*
    P3811
    */
    #include<bits/stdc++.h>
    
    #define N 3000007
    #define ll long long
    
    using namespace std;
    ll n,m,p;
    ll inv[N];
    
    inline ll read()
    {
        ll x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        n=read();p=read();inv[1]=1; 
        for(int i=2;i<=n;i++)
        {
            inv[i]=(p-p/i)*inv[p%i]%p;
        }
        for(int i=1;i<=n;i++) printf("%lld
    ",inv[i]);
        return 0;
    }
    线性求逆元

     6.欧拉函数

    int get_phi(int x)
    {
        int ret=1;
        for(int i=1;prime[i]*prime[i]<=x;i++)
        {
            if(x%prime[i]==0)
            {
                ret*=prime[i]-1;x/=prime[i];
                while(x%prime[i]==0) x/=prime[i],ret*=prime[i];
            }
        }
        if(x>1) ret*=x-1;
        return ret;
    }
    beautiful!
    void get_phi()
    {
        cnt = 0;
        memset(is_prime, true, sizeof(is_prime));
        phi[1] = 1;
        for(int i=2; i<N; i++)
        {
            if(is_prime[i])///素数
            {
                p[cnt++] = i;
                phi[i] = i-1;///素数的欧拉函数值是素数- 1
            }
            for(int j=0; j<cnt; j++)
            {
                if(i*p[j] > N) break;
                is_prime[i*p[j]] = false;///素数的倍数,所以i*p[j]不是素数
                if(i%p[j] == 0)///性质:i mod p == 0, 那么 phi(i * p) == p * phi(i)
                {
                    phi[i*p[j]] = p[j] * phi[i];
                    break;
                }
                else phi[i*p[j]] = (p[j]-1) * phi[i];///i mod p != 0, 那么 phi(i * p) == phi(i) * (p-1) 
            }
        }
    }
    线筛欧拉函数

     7.高斯消元

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    int n;
    double f[101][101],ans[101];
    const double eps=1e-12;
    
    int dcmp(double x)
    {
        if(x<=eps && x>=-eps) return 0;
        return (x>0)?1:-1;
    }
    
    bool gauss()
    {
        for(int i=1;i<=n;i++)
        {
            int num=i;
            for(int j=i+1;j<=n;j++)
              if(dcmp(f[i][j]-f[num][i])>0)
                num=j;
            if(num!=i)
              for(int j=1;j<=n+1;j++)
                swap(f[i][j],f[num][j]);
            for(int j=i+1;j<=n;j++)
              if(dcmp(f[j][i]))
              {
                    double t=f[j][i]/f[i][i];
                    for(int k=1;k<=n+1;k++)
                      f[j][k]-=t*f[i][k];
              }
        }
        
        for(int i=n;i>=1;i--)
        {
            if(dcmp(f[i][i])==0) return 0;
            for(int j=i+1;j<=n;j++) f[i][n+1]-=f[i][j]*ans[j];
            ans[i]=f[i][n+1]/f[i][i];
        }return 1;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n+1;j++)
            scanf("%lf",&f[i][j]);
            
        if(gauss())
          for(int i=1;i<=n;i++)
            printf("%.2lf
    ",ans[i]);
        else puts("No Solution
    ");
        return 0;
    }
    P3389

     8.中国剩余定理

    void exgcd(int a,int b)
    {
        if(b==0)
        {
            x=1;y=0;
            return;
        }
        exgcd(b,a%b);
        int tmp=x;x=y;y=tmp-(a/b)*y;
    }
    
    int CRT(int a[],int m[],int n)
    {
        int M=1,ans=0;
        for(int i=1;i<=n;i++) M*=m[i];
        for(int i=1;i<=n;i++)
        {
            int Mi=M/m[i];
            exgcd(Mi,m[i]);
            ans=(ans+Mi*x*a[i])%M;
        }
        if(ans<0) ans+=M;
        return ans;
    }
    CRT

     9.组合数

    inline void combination()
    {
        for(int i=0;i<=n;i++)  
            for(int j=0;j<=i;j++)  
                if(!j || i==j)  c[i][j]=1;  
                else  c[i][j]=c[i-1][j-1]+c[i-1][j];  
        c[0][0]=0;  
        return;  
    }
    递推

     10.Lucas定理

    int ksm(int a,int b,int p)
    {
        int res=1;
        while(b)
        {
            if(b&1) res=res*a%p;
            b>>=1;a=a*a%p;
        }return res;
    }
    
    int C(int n,int m,int p)
    {
        if(m>n)return 0;
        return  fac[n]*ksm(fac[m]*fac[n-m],p-2,p)%p;
    }
    
    int Lus(int n,int m,int p)
    {
        if(m==0) return 1;
        return (C(n%p,m%p,p)*Lus(n/p,m/p,p))%p;
    }
    ~
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    python面向对象三大特性之一封装
    python面向对象的三大特性之一多态
    python之子类调用父类的两种方式
    python之接口继承
    python之组合与继承的使用场景
    Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks(paper)
    lesson9-小象学院cv
    tips
    C5-fasterrcnn-小象cv-code
    C4-ResNet-TF-小象cv-code
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7463761.html
Copyright © 2011-2022 走看看