[ SDOI 2010 ] 古代豬文
阿新 • • 發佈:2018-11-19
\(\\\)
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; }