[ SDOI 2010 ] 古代猪文
\(\\\)
Description
一句话题意:
设 \(x=\sum_{d|n} C_n^d\),求 \(G^x\pmod {999911659}\) 。
从原题面大段语文中其实不难推出所求。
\(\\\)
Solution
以前一不敢碰..... 今天做做发现是个水题
显然问题在指数上,而不是整个式子。
暴力检验一下,发现模数为质数。根据费马小定理,\(a^k\equiv a^{k\pmod {p-1}}\pmod{p-1}\) 。
所以所求化为 \(\sum_{d|n}C_{n}^d\pmod{999911658}\) woc怕不是要EXCRT
后来发现这个模数很萎.....标准分解一下 \(999911659=2\times3\times4679\times35617\) 。
叫什么 square-free-number ,其实就是只为考个 \(CRT\) 强行凑了一个数罢了......
对四个质数分别用 \(Lucas\) 搞一下,然后 \(CRT\) 合并就好了。
其实最后还是被坑了一下,注意最外层快速幂的模数跟 CRT 合并的时候的 M 不同。
还要特判 \(a\ |\ p\) 的情况,因为这种情况下费马小定理不成立。
\(\\\)
Code
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define R register
#define N 50010
#define mo 999911658ll
using namespace std;
typedef long long ll;
ll mod[5]={0,2,3,4679,35617},m[5],fac[N];
inline void init(ll p){
fac[0]=1;
for(R ll i=1;i<=p;++i) fac[i]=fac[i-1]*i%p;
}
inline ll qpow(ll x,ll t,ll p){
ll res=1;
while(t){
if(t&1) (res*=x)%=p;
(x*=x)%=p; t>>=1;
}
return res;
}
ll C(ll n,ll m,ll p){
if(m>n) return 0;
return fac[n]*qpow(fac[m],p-2,p)%p*qpow(fac[n-m],p-2,p)%p;
}
ll lucas(ll n,ll m,ll p){
if(n<m) return 0;
if(!m||!n) return 1;
return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
inline ll solve(ll n,ll p){
init(p);
ll t=sqrt(n),res=0;
for(R ll i=1;i<=t;++i)
if(n%i==0){
(res+=lucas(n,i,p))%=p;
if(n/i!=i) (res+=lucas(n,n/i,p))%=p;
}
return res;
}
inline ll CRT(ll n){
ll res=0;
for(R ll i=1;i<=4;++i){
m[i]=mo/mod[i];
res=(res+m[i]*solve(n,mod[i])%mo*qpow(m[i],mod[i]-2,mod[i]))%mo;
}
return res;
}
int main(){
ll n,g;
scanf("%lld%lld",&n,&g);
if(g%(mo+1)==0){puts("0");return 0;}
printf("%lld\n",qpow(g,CRT(n),mo+1));
return 0;
}