zoukankan      html  css  js  c++  java
  • 模板

     一.数论 讲解

    求单一欧拉函数 时间:O ( $sqrt{n}$ )

    int eular(int a)
    {
        int ans=1;
        for(int i=2;i*i<=a;i++) {
            if(!(a%i)) {
                a/=i;
                ans*=i-1;
                for(;!(a%i);a/=i) ans*=i;
            }
        }
        if(a>1) ans*=a-1;
        return ans;
    }
    View Code

    欧拉/莫比乌斯/质数线性筛 时间:O ( $n$ )

    int pri[MN+5],cnt,miu[MN+5],phi[MN+5];
    bool ok[MN+5];
    void init()
    {
        phi[1]=1;
        for(int i=2;i<=MN;i++)
        {
            if(!ok[i]){pri[++cnt]=i;phi[i]=i-1;miu[i]=-1;}
            for(int j=1;j<=cnt&&pri[j]*i<=MN;j++)
            {
                ok[pri[j]*i]=1;
                if(i%pri[j])
                {
                    phi[pri[j]*i]=phi[i]*(pri[j]-1);
                    miu[pri[j]*i]=-miu[i];
                }
                else
                {
                    phi[pri[j]*i]=phi[i]*pri[j];
                    miu[pri[j]*i]=0;
                    break;
                }
            }
        }
    }
    View Code

    逆元线性筛(条件:模数为质数)时间:O ( $n$ )

    typedef long long ll;
    int inv[MN+5];
    void init()
    {
        inv[1]=1;
        for(int i=2;i<=MN;i++) inv[i]=(ll)(Mod-Mod/i)*inv[Mod%i]%Mod;
    }
    View Code

    费马小定理求逆元(条件:模数为质数) 时间:O ( $log_2Mod$ )

    typedef long long ll;
    int quipow(int a,int b,int Mod) //快速幂
    {
        int ret=1;
        for(;b;b>>=1,a=(ll)a*a%Mod) if(b&1) ret=(ll)ret*a%Mod;
        return ret;
    }
    int getinverse(int x,int Mod) { //费马小定理 
        return quipow(x,Mod-2,Mod);
    }
    View Code

    gcd(欧几里得算法) 时间:O ( $log_2a$ )

    int Gcd(int a,int b){return b==0?a:Gcd(b,a%b);}
    View Code

    exgcd(扩展欧几里得算法) 时间:O ( $log_2a$ )

    void exgcd(int a,int b,int&x,int&y)
    {
        if(!b) x=1,y=0;
        else exgcd(b,a%b,y,x),y-=a/b*x;
    }
    View Code

    exgcd求逆元 (条件:$gcd(a,Mod)$ $=$ $1$ )  时间:O ( $log_2a$ )

    int getinverse(int x,int Mod) {
        int ans,y;
        exgcd(x,Mod,ans,y);
        return (ans%Mod+Mod)%Mod;
    }
    View Code

    欧拉函数求逆元(条件:$gcd(a,Mod)$ $=$ $1$ )  时间:O ( $sqrt{a}$ )

    int quipow(int a,int b,int Mod) //快速幂
    {
        int ret=1;
        for(;b;b>>=1,a=(ll)a*a%Mod) if(b&1) ret=(ll)ret*a%Mod;
        return ret;
    }
    int eular(int a) //求欧拉函数
    {
        int ans=1;
        for(int i=2;i*i<=a;i++) {
            if(!a%i) {
                a/=i;
                ans*=i-1;
                for(;a%i;a/=i) ans*=i;
            }
        }
        if(a>1) ans*=a-1;
        return ans;
    }
    int getinverse(int a,int Mod) { //欧拉函数求逆元
        return quipow(a,eular(Mod)-1,Mod);
    }
    View Code

    bsgs(大步小步)(拔山盖世) (条件:$gcd(a,p)$ $=$ $1$) 时间:O( 哈希复杂度 $ imes$ $sqrt{Mod}$ )

    int bsgs(int a,int b,int p) //a^x=b mod p
    {
        std::map<int, int> h;
        if(b==1) return 0;
        int m=ceil(sqrt(p)),inv=getinverse(a,p),now=quipow(a,m-1,p),s;
        for(int i=m-1;i>=0;i--,now=(ll)now*inv%p) { //将b*a^(0~m-1)丢进hash表
            s=(ll)now*b%p;
            if(h.find(s)==h.end()) h.insert(P(s,i));
        }
        inv=quipow(a,m,p);now=1;
        for(int i=1;i<=m;i++) //在hash表里找与a^(i*m)相等的值
        {
            now=(ll)now*inv%p;
            if(h.find(now)!=h.end()) return i*m-h[now];
        }
        return -1;
    }
    View Code

    exbsgs(扩展大步小步) 时间:O ( $log_2a$ $+$ bsgs复杂度 )

    int exbsgs(int a,int b,int p) //a^x=b mod p
    {
        int k=0;
        for(int d=Gcd(a,p);d>1;d=Gcd(a,p)) //找到最小的k使得gcd(a,p/gcd(a^k,p))=1
        {
            if(b%d) return -1;
            b/=d;p/=d;
            b=(ll)b*getinverse(a/d,p)%p;
            k++;
        }
        int ans=bsgs(a,b,p);
        if(ans==-1) return -1;
        else return ans+k;
    }
    View Code

    CRT(中国剩余定理/孙子定理)(条件:对于$forall i,j , i eq j$,$gcd(m_{i},m_{j}) = 1$) 时间:O ( $n$ $cdot$ $log_2m_{i}$ )

    int CRT(int n,int *a,int *m) //X = a[i] mod m[i]
    {
        int M=1,ans=0,w;
        for(int i=1;i<=n;i++) M*=m[i];
        for(int i=1;i<=n;i++) {
            w=M/m[i];
            ans=(ans+(ll)a[i]*w%M*getinverse(w,m[i])%M)%M;
        }
        return (ans%M+M)%M;
    }
    View Code

     Lucas定理 (条件:$pin mathbb{P}$) 时间:O ( $log_pn$ $cdot$ $log_2p$ $+$ $p$ )

    int C(int n,int m,int Mod) {
        if(m>n) return 0;
        return (ll)fac[n]*getinverse(fac[m],Mod)%Mod*getinverse(fac[n-m],Mod)%Mod;
    }
    int lucas(int n,int m,int p) //C(n,m) % p
    {
        if(!m) return 1;
        return (ll)C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
    }
    View Code

    exlucas(扩展lucas) 时间:设P质因数分解后为$ = p_{1}^{k_{1}} cdot p_{2}^{k_{2}} cdot .... cdot p_{t}^{k_{t}}$,则复杂度为O ( CRT复杂度+$sum_{i=1}^{t} p_{i}^{k_{i}} cdot log_{p_{i}}n$ )

    int calc(int n,int p,int pt)
    {
        if(!n) return 1;
        int ans=1;
        for(int i=2;i<=pt;i++) if(i%p) ans=(ll)ans*i%pt;
        ans=quipow(ans,n/pt,pt);
        for(int i=2;i<=n%pt;i++) if(i%p) ans=(ll)ans*i%pt;
        return (ll)ans*calc(n/p,p,pt)%pt;
    }
    int mutilucas(int n,int m,int p,int pt) //C(n,m) mod p^t
    {
        int cnt=0;
        for(int i=n;i;i/=p) cnt+=i/p;
        for(int i=m;i;i/=p) cnt-=i/p;
        for(int i=n-m;i;i/=p) cnt-=i/p;
        return (ll)quipow(p,cnt,pt)*calc(n,p,pt)%pt*getinverse(calc(m,p,pt),pt)%pt*getinverse(calc(n-m,p,pt),pt)%pt;
    }
    int exlucas(int n,int m,int P) //C(n,m) mod P
    {
        if(m>n) return 0;
        int cnt=0,p[40],a[40];
        for(int i=2;i*i<=P;i++)
        {
            if(P%i==0) {
                p[++cnt]=1;
                for(;P%i==0;) {
                    P/=i;
                    p[cnt]*=i;;
                }
                a[cnt]=mutilucas(n,m,i,p[cnt]);
            }
        }
        if(P>1) p[++cnt]=P,a[cnt]=mutilucas(n,m,P,P);
        return CRT(cnt,a,p);
    }
    View Code
  • 相关阅读:
    Ubuntu adb devices :???????????? no permissions (verify udev rules) 解决方法
    ubuntu 关闭显示器的命令
    ubuntu android studio kvm
    ubuntu 14.04版本更改文件夹背景色为草绿色
    ubuntu 创建桌面快捷方式
    Ubuntu 如何更改用户密码
    ubuntu 14.04 返回到经典桌面方法
    ubuntu 信使(iptux) 创建桌面快捷方式
    Eclipse failed to get the required ADT version number from the sdk
    Eclipse '<>' operator is not allowed for source level below 1.7
  • 原文地址:https://www.cnblogs.com/zzpcd/p/10332315.html
Copyright © 2011-2022 走看看