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));
    }
  • 相关阅读:
    OnClick方法与Click事件
    词法,语法,语义
    静态成员与实例成员
    依赖属性 DependencyProperty
    依赖,关联,聚合,合成
    数据可视化
    ref 与out
    理解TCP为什么需要进行三次握手(白话)
    禁止访问网站中所有的动态页面
    linux 重命名文件和文件夹
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6556450.html
Copyright © 2011-2022 走看看