zoukankan      html  css  js  c++  java
  • BZOJ 1951 Lucas定理+CRT

    思路:

    枚举约数

    套个裸的Lucas+CRT就完了...

    //By SiriusRen
    #include <cmath>
    #include <cstdio>
    using namespace std;
    #define int long long
    const int M=999911658,N=35617;
    void exgcd(int a,int b,int &x,int &y){
        if(!b){x=1,y=0;return;}
        exgcd(b,a%b,x,y);
        int temp=x;x=y;y=temp-a/b*y;
    }
    int CRT(int *a,int *m,int num){
        int ans=0;
        for(int i=1;i<=num;i++){
            int x,y;
            exgcd(M/m[i],m[i],x,y);
            ans=(ans+M/m[i]*x%M*a[i])%M;
        }return ans;
    }
    int power(int x,int y){
        int ans=1;
        while(y){
            if(y&1)ans=ans*x%(M+1);
            x=x*x%(M+1),y>>=1;
        }return ans;
    }
    int m[5]={0,2,3,4679,35617},n,g,fac[N],inv[N],sqr,s[N],top,ans[5],T;
    int C(int x,int y){
        if(x<y)return 0;
        if(x<m[T]&&y<m[T])return fac[x]*inv[y]%m[T]*inv[x-y]%m[T];
        return C(x/m[T],y/m[T])*C(x%m[T],y%m[T])%m[T];
    }
    signed main(){
        scanf("%lld%lld",&n,&g),sqr=sqrt(n);
        for(int i=1;i<sqr;i++)if(n%i==0)s[++top]=i,s[++top]=n/i;
        if(sqr*sqr==n)s[++top]=sqr;
        if(n%sqr==0&&sqr*sqr!=n)s[++top]=sqr,s[++top]=n/sqr;
        fac[1]=fac[0]=inv[1]=inv[0]=1;
        for(T=1;T<=4;T++){
            for(int i=2;i<m[T];i++)fac[i]=fac[i-1]*i%m[T];
            for(int i=2;i<m[T];i++)inv[i]=(m[T]-m[T]/i)*inv[m[T]%i]%m[T];
            for(int i=2;i<m[T];i++)inv[i]=inv[i]*inv[i-1]%m[T];
            for(int i=1;i<=top;i++)ans[T]=(ans[T]+C(n,s[i]))%m[T];
        }
        printf("%lld
    ",power(g,CRT(ans,m,4)+M));
    }
  • 相关阅读:
    SQL*PLUS命令的使用大全
    Oracle总结
    SQL*PLUS命令的使用大全
    Java经典面试题
    学习Java的30个基本概念
    Java经典面试题
    学习Java的30个基本概念
    Oracle总结
    ORACLE大数据量下的分页解决方法
    XAMPP修改80和443端口及创建虚拟目录
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6556450.html
Copyright © 2011-2022 走看看