Ancient pig culture (number theory)

Portal

Regarded as a more integrated number of topics it! We use Euler's theorem, Chinese remainder theorem, Lucas them.

But the whole is still very simple questions.

(Picture taken from Luogu Bo-off)

Subject to the effect that seek

Because the index is too big but it is a prime number, we consider getting a corollary of Euler's theorem

Because related to the number of combinations, we will think of using Lucas theorem, but 999 911 658 This modulus is too large (like Lucas modulus can do 1e5 level) and not a prime number, not directly Lucas

We split into 2 999 911 658 * 4679 * 35617 * 3 four prime numbers, for each prime number is calculated , the result referred to as a1, a2, a3, a4

X end up merging with Chinese remainder theorem

#include<bits/stdc++.h>
#define LL long long
#define mod 999911658
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
int b[]={0,2,3,4679,35617};
LL fac[36000],invfac[36000],a[5];
LL quick(LL a,LL x,LL p)
{
    LL ans=1;
    while(x)
    {
        if(x&1)ans=ans*a%p;
        a=a*a%p;x>>=1;
    }
    return ANS% P; 
} 

void the init ( int P) 
{ 
    Memset (invfac, 0 , the sizeof (invfac)); 
    FAC [ 0 ] = . 1 ;
     for ( int I = . 1 ; I <= P; I ++) FAC [ I] FAC = [I- . 1 ] * I% P; 
    invfac [P] = Quick (FAC [P], p- 2 , P); 
    invfac [P - . 1 ] = Quick (FAC [p- . 1 ], P - 2 , p); // Note that not the FAC [p] start, because it must be pushed 0, mod p thing is 
    for ( int I = p-1;i>=1;--i)invfac[i-1]=invfac[i]*i%p;
}
LL lucas(int n,int m,int p)
{
    if(n<m)return 0;
    if(n<p&&m<p) return fac[n]*invfac[m]%p*invfac[n-m]%p;
    return lucas(n/p,m/p,p)*lucas(n%p,m%p,p)%p;
} 
LL res=0;
void CRT()
{
    for(int i=1;i<=4;++i)
      res=(res+a[i]*(mod/b[i])%mod*quick(mod/b[i],b[i]-2,b[i])%mod)%mod;
}
int main()
{
    int n=read(),g=read();
    if(g%(mod+1)==0) 
    {
        printf("0\n");
        return 0;
    }
    for(int k=1;k<=4;++k)
    {
        init(b[k]);
        for(int i=1;i*i<=n;++i)
        {
            if(n%i)continue;
            a[k]=(a[k]+lucas(n,i,b[k]))%b[k];
            if(i*i!=n)a[k]=(a[k]+lucas(n,n/i,b[k]))%b[k];
        }
    }
    CRT();
    printf("%lld\n",quick(g,res,mod+1)); 
} 
View Code

Guess you like

Origin www.cnblogs.com/yyys-/p/11295540.html