bzoj Thousand Questions Project 323: bzoj1951: [Sdoi2010] Ancient Pig Text (Lucas+CRT+Euler's Theorem)

https://www.lydsy.com/JudgeOnline/problem.php?id=1951

 

Euler's power reduction

Then modulus prime factorization

The result of calculating the number of combinations separately, the Chinese remainder theorem merges

 

#include<cmath>
#include<cstdio>
#include<iostream> 

using namespace std;

const  int mod = 999911659 ;
const  int phi = mod- 1 ;

typedef long long LL;

int p[5]; 
LL mul[5][35618];

LL c[5];

void pre()
{
    p[1]=2;
    p[2]=3;
    p[3]=4679;
    p[4]=35617;
    for(int i=1;i<=4;++i)
    {
        mul[i][0]=1;
        for(int j=1;j<=35617;++j)  mul[i][j]=mul[i][j-1]*j%p[i];    
    }
}

LL gcd(LL a,LL b)
{
    return !b ? a : gcd(b,a%b);
}

LL Pow(LL a,LL b,LL mod)
{
    LL ans=1;
    for(;b;a=a*a%mod,b>>=1)
        if(b&1) ans=ans*a%mod;
    return ans;
}

LL C(LL n,LL m,int i)
{
    if(m>n) return 0;
    return mul[i][n]*Pow(mul[i][m],p[i]-2,p[i])%p[i]*Pow(mul[i][n-m],p[i]-2,p[i])%p[i];
}

LL Lucas(LL n,LL m,int i)
{
    if(m>n) return 0;
    LL ans=1;
    for(;m;n/=p[i],m/=p[i]) ans=(ans*C(n%p[i],m%p[i],i))%p[i];
    return ans;
}

void exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b) x=1,y=0;
    else exgcd(b,a%b,y,x),y-=a/b*x;
}

intmain ()
{
    pre();
    LL n,g;
    cin>>n>>g;
    if(gcd(g,mod)!=1) 
    {
        printf("0");
        return 0;
    }
    int m=sqrt(n);
    for(int i=1;i<=m;++i)
        if(n%i==0)
        {
            for(int j=1;j<=4;++j) c[j]=(c[j]+Lucas(n,i,j))%p[j];
            if(n/i!=i) 
            for(int j=1;j<=4;++j) c[j]=(c[j]+Lucas(n,n/i,j))%p[j]; 
        }
    LL ans=0;
    LL Mi,mi,x,y;
    for(int i=1;i<=4;++i)
    {
        Mi =phi/ p[i];
        mi=p[i];
        exgcd(My,my,x,y);
        x=(x%mi+mi)%mi;
        if(!x) x+=mi;
        ans+=c[i]*Mi*x;
    }
    years = Pow(g,years,mod);
    cout << years;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325297887&siteId=291194637