SDOI2011古代朱文

SDOI2011古代朱文

#include<algorithm>/*{{{*/
#include<cctype>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<vector>
using namespace std;
typedef long long lld;
typedef long double lf;
typedef unsigned long long uld;
typedef pair<int,int> pii;
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define ROF(i,a,b) for(int i=(a);i>=(b);--i)
namespace RA{
    int r(int p){return 1ll*rand()*rand()%p;}
    int r(int L,int R){return r(R-L+1)+L;}
}
namespace IO{
    char nc(){
        static char bf[100000],*p1=bf,*p2=bf;
        return p1==p2&&(p2=(p1=bf)+
                fread(bf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    int rd(){
        int res=0; char c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c))res=res*10+c-'0',c=getchar();
        return res;
    }
}/*}}}*/
/******************heading******************/
//2 3 4679 35617
int fc[4][40000],iv[4][40000];
int pw(int a,int m,const int p){
    int res=1;
    while(m)m&1?res=1ll*res*a%p:0,a=1ll*a*a%p,m>>=1;
    return res;
}
void init(int p,int *fac,int *inv){//预处理mod p的阶乘,逆元
    fac[0]=1;
    FOR(i,1,p-1)fac[i]=1ll*fac[i-1]*i%p;
    inv[p-1]=pw(fac[p-1],p-2,p);
    ROF(i,p-1,1)inv[i-1]=1ll*inv[i]*i%p;
}
int binom(int n,int m,int p,const int *fac,const int *inv){
    if(n<m)return 0;
    if(n>=p||m>=p)
        return 1ll*binom(n/p,m/p,p,fac,inv)*binom(n%p,m%p,p,fac,inv)%p;
    return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
}
int calc(int n,int p,const int *fac,const int *inv){
    int res=0;
    for(int i=1;i*i<=n;i++){
        if(n%i)continue;
        res=(res+binom(n,i,p,fac,inv))%p;
        if(i*i!=n)res=(res+binom(n,n/i,p,fac,inv))%p;
    }
    return res;
}
int n,g;
int M=999911658,ans=0;
int main(){
    scanf("%d%d",&n,&g);
    g%=(M+1);
    if(g==0)return puts("0"),0;
    init(2,fc[0],iv[0]);
    init(3,fc[1],iv[1]);
    init(4679,fc[2],iv[2]);
    init(35617,fc[3],iv[3]);
    int x[5],m[]={0,2,3,4679,35617};
    x[1]=calc(n,2,fc[0],iv[0]);
    x[2]=calc(n,3,fc[1],iv[1]);
    x[3]=calc(n,4679,fc[2],iv[2]);
    x[4]=calc(n,35617,fc[3],iv[3]);
    //printf("%d %d %d %d
",x[1],x[2],x[3],x[4]);
    //merge x1,x2,x3,x4 and print the answer
    FOR(i,1,4){
        int wi=M/m[i];
        int pi=pw(wi%m[i],m[i]-2,m[i]);
        //printf("wi:%d,pi:%d
",wi,pi);
        ans=(ans+1ll*wi*pi%M*x[i]%M)%M;
    }
    printf("%d
",pw(g%(M+1),ans,M+1));
    return 0;
}

原文地址:https://www.cnblogs.com/sshwy/p/11213550.html