码迷,mamicode.com
首页 > 其他好文 > 详细

【 模_板 】

时间:2017-11-06 18:03:53      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:double   排列组合   情况   break   tin   欧拉函数   etc   matrix   char   

 

  • 数论知识

技术分享
#include <cstring>
#include <cstdio>
#include <cmath>

#define LL long long

inline void read(int &x)
{
    x=0; register char ch=getchar();
    for(; ch>9||ch<0; ) ch=getchar();
    for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0;
}

const int mod(1e9+7);
const int N(1000005);

bool no_pri[N];
LL fac[N],inv[N];
int cnt,pri[N],phi[N];

namespace Number_Theory {
    
    inline LL Mul(LL a,int b,int p) //慢速乗,防乗爆 
    {
        LL ret=0;
        for(; b; b>>=1, a<<=1,a%=p)
            if(b&1) ret+=a, ret%p;
        return ret;
    }
    
    inline LL Pow(LL a,int b,int p) // 快速幂 
    {
        LL ret=1;
        for(; b; b>>=1, a*=a,a%=p)
            if(b&1) ret*=a, ret%=p;
        return ret;
    }
    
    inline bool judge_ss(int x)
    {
        if(x<2) return 0;
        for(int i=2; i*i<=x; ++i)
            if(x%i==0) return 0;
        return 1;
    }
    
    inline void Euller(int n)
    {
/*        
        (1) 若(N%a==0 && (N/a)%a==0) 则有:E(N)=E(N/a)*a;
        (2) 若(N%a==0 && (N/a)%a!=0) 则有:E(N)=E(N/a)*(a-1);  
        其中a是N的质因数。
        关于欧拉函数还有以下性质:
        (1) phi[p]=p-1;  (p为素数);
        (2)若N=p^n(p为素数),则 phi[N]=(p-1)*p^(n-1);
*/        
        for(int i=2; i<=n; ++i)
        {
            if(!no_pri[i]) pri[++cnt]=i,phi[i]=i-1;
            for(int j=1; j<=cnt; ++j)
            {
                if(pri[j]*i>n) break;
                no_pri[pri[j]*i]=true;
                if(i%pri[j]==0)
                {
                    phi[i*pri[j]]=phi[i]*pri[j]; break;
                }
                else phi[i*pri[j]]=phi[i]*(pri[j]-1);
            }
        }
    }
    
    inline LL Phi(LL x)
    {
        LL ret=1;
        for(int i=2; i<=x; ++i)
        {
            if(x%i) continue;
            ret*=i-1, x/=i;
            for(; x%i==0; )
                ret*=i,x/=i;
        }
        if(x>1) ret*=x-1;
        return ret;
    }
    
    inline LL exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b) { x=1,y=0; return a;}
        LL ret=exgcd(b,a%b,x,y),tmp=x;
        x=y; y=tmp-a/b*y; return ret;
    }
    
    inline LL Fermat(LL a,LL p) // p为素数 
    {
        return Pow(a,p-2,p);
    }
    
    inline LL Pre_inv(int p) // a/b%mod --> a*inv(b,mod) 
    {
        fac[0]=fac[1]=inv[1]=1;
        for(int i=2; i<N; ++i)
        {
            fac[i]=1ll*fac[i-1]%p*i%p;
            inv[i]=1ll*inv[p%i]*(p-p/i)%p; //线性求逆元
            /*  拓展欧几里得求逆元 
            LL x,y,gcd=exgcd(i,mod,x,y);
            inv[i]= gcd==1 ?(x+mod)%mod :-1;
            */
            /* 欧拉函数求逆元 
            Euller();
            inv[i]=Fermat(i,mod);
            */
        }
    }
    
    inline LL CRT(LL *m,LL *p,int n) //中国剩余定理,互质不互质情况 
    {
        LL x,y,tmp,gcd,b,c;
        LL ret=m[1],a=p[1],mod;
        for(int i=2; i<=n; ++i)
        {
            tmp=m[i],b=p[i],c=tmp-ret;
            gcd=exgcd(a,b,x,y);
            if(c%gcd) return -1;
            x*=c/gcd, mod=b/gcd;
            for(x+=mod; x>=mod; ) x-=mod;
            ret+=a*x, a*=mod;
        }
        return ret?ret:(ret+a);
    }
    
    struct Matrix_fb {     // 矩阵优化菲波那切数列 
        LL e[2][2];
        void init_base()
        {
            e[0][0]=1;
            e[0][1]=1;
            e[1][0]=1;
            e[1][1]=0;
        }
        void init_ans()
        {
            e[0][0]=e[0][1]=1;
            e[1][0]=e[1][1]=0;
        }
        Matrix_fb operator * (Matrix_fb x) const 
        {
            Matrix_fb ret;
            for(int i=0; i<2; ++i)
                for(int j=0; j<2; ++j)
                {
                    ret.e[i][j]=0;
                    for(int k=0; k<2; ++k)
                      ret.e[i][j]+=e[i][k]*x.e[k][j],ret.e[i][j]%=mod;
                }
            return ret;
        }
    }ans,base;
    
    inline LL Fibonacci(int n) 
    //斐波那契数列  gcd( f[a],f[b] )= f[ gcd(a,b) ], f[i]=f[i-1]+f[i-2]
    {
        double x=sqrt(5.0);
        return pow(((1+x)/2),n)/x - pow(((1-x)/2),n)/x; // 通式 
        if(n==1||n==2) return 1;
        for( n-=2; n; n>>=1,base=base*base)
            if(n&1) ans=ans*base;
        return ans.e[0][0];
    }
}

// 排列组合 
namespace Permutations {
    
    inline void Pre_C(int n,int p) // 预处理组合数 
    {
        LL C[n][n];
        memset(C,0,sizeof(C));
        for(int i=1; i<n; ++i)
        {
            C[i][i]=C[i][0]=1;
            for(int j=1; j<i; ++j)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
        }
    }
    
    LL C(LL n,LL m,LL p)
    {
        if(m>n) return 0;
        LL t1=Number_Theory::Fermat(fac[m],p);
        LL t2=Number_Theory::Fermat(fac[n-m],p);
        return fac[n]%p*t1%p*t2%p;
    }
    
    LL Luc(LL n,LL m,LL p)
    {
        if(n<m) return 0;
        if(m==0) return 1;
        return (C(n%p,m%p,p))*Luc(n/p,m/p,p)%p;
    }
    
    inline void Use_luc(int n,int m,int p)
    {
        Number_Theory:: Pre_inv(p);
        printf("%lld\n",Luc(n,m,p));
    }
}

int Presist()
{
    
    return 0;
}

int Aptal=Presist();
int main(int argc,char**argv){;}
数论知识

 

【 模_板 】

标签:double   排列组合   情况   break   tin   欧拉函数   etc   matrix   char   

原文地址:http://www.cnblogs.com/Shy-key/p/7794154.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!