【BZOJ】【P1951】【Sdoi2010】【古代猪文】【题解】【数论】

来源:互联网 发布:ubuntu 查看重启日志 编辑:程序博客网 时间:2024/05/19 04:05

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1951

一直没有发现我的中国剩余定理有bug

原来的:

LL china(int n,int *a,int *m){LL M=1,d,x=0,y;for(int i=0;i<n;i++)M*=m[i];for(int i=0;i<n;i++){LL w=M/m[i];d=exgcd(m[i],w,d,y);x=(x+y*w*a[i])%M;}return (x+M)%M; }

 现在的:

LL china(int n,int *a,int *m){LL M=1,d,x=0,y;for(int i=0;i<n;i++)M*=m[i];for(int i=0;i<n;i++){LL w=M/m[i];d=exgcd(m[i],w,d,y);x=(x+y*w*a[i])%M;}while(x<=0)x+=M;return x;}

LRJ真是坑啊……

Code:

#include<cstdio>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;LL N,G;LL fac[35619];LL a[4],m[4]={2,3,4679,35617};LL exgcd(LL a,LL b,LL &x,LL &y){    if(!b){x=1;y=0;return a;}    LL d=exgcd(b,a%b,x,y);LL t=x;    x=y;y=t-a/b*y;return d;}LL power(LL x,LL k,LL p){    LL ans=1;    for(;k;k>>=1){        if(k&1)ans=(ans*x)%p;        x=(x*x)%p;    }return ans;}LL inv(LL a,LL n){LL x,y,d=exgcd(a,n,x,y);return d==1?(x+n)%n:-1;}void get_fac(LL p){fac[0]=1;for(int i=1;i<=p;i++)fac[i]=i*fac[i-1]%p;}LL C(LL n,LL m,LL p){if(n<m)return 0;return fac[n]*inv(fac[m]*fac[n-m]%p,p)%p;}LL china(int n,LL *a,LL *m){    LL M=1,x=0,y,d;    for(int i=0;i<n;i++)M*=m[i];    for(int i=0;i<n;i++){        int w=M/m[i];        d=exgcd(m[i],w,d,y);        x=(x+y*w*a[i])%M;    }while(x<=0)x+=M;    return x;}LL Lucas(LL n,LL m,LL p){    LL ans=1;    while(n&&m){        LL a=n%p,b=m%p;        if(a<b)return 0;        ans=(ans*C(a,b,p))%p;        n/=p;m/=p;    }return ans%p;}int main(){         cin>>N>>G;//G%=999911659;    for(int i=0;i<4;i++){        get_fac(m[i]);        for(LL j=1;j*j<=N;j++){            if(N%j==0){                a[i]=(a[i]+Lucas(N,j,m[i]))%m[i];                if(j*j!=N)                a[i]=(a[i]+Lucas(N,N/j,m[i]))%m[i];                         }        }    }LL ans=china(4,a,m);    cout<<power(G,ans,999911659)<<endl;    return 0;}


0 0
原创粉丝点击