1. 程式人生 > >【學術篇】SDOI2010 古代豬文

【學術篇】SDOI2010 古代豬文

避免 matrix 並不是 std %x 答案 post cfa pri

這裏可能包含傳送門

又雙叒叕數論大雜燴...

定理什麽我都不會證

題目很長很啰嗦 但是題意很顯然... 化完式子之後就是這麽個東東:\(G^{\sum_{k|n}C_k^{\frac{n}{k}}}\ mod\ p\)
看上去好像也並不怎麽好求...
\(p\)是個質數,由於費馬小定理,我們知道\(G^{p-1}\equiv 1(mod\ p)\),
所以我們相當於要求\(G^{{\sum_{k|n}C_k^{\frac{n}{k}}} \% (p-1)}\ mod\ p\)

看到大組合數取模自然想到Lucas定理...
可是這裏的\(p-1\)並不是質數...
質因數分解:\(999911658=2*3*4679*35617\)

(Emmmm這裏我偷了個懶在線分解了←_←
對四個質數分別做Lucas就可以寫出下面這一堆東西, 然後直接CRT(中國剩余定理(孫子定理))就行了...
\[ \left\{\begin{matrix} ans\equiv c_1(mod\ 2) \\ ans\equiv c_2(mod\ 3) \ans\equiv c_3(mod\ 4679) \ans\equiv c_4(mod\ 35617) \end{matrix}\right. \]
好像就做完了OvO 說起來很簡單的樣子...
Emmmm,所以這題是不是還能強行給出模數然後考擴展Lucas

地球人看不懂的代碼

(我對不起黨對不起人民對不起社會地又雙叒叕壓行了)

~~誰讓數論題一行一個函數壓行太舒服了呢→_→~~

#include <cmath>
#include <cstdio>
typedef long long LL;
const int P=999911658;const int pr[]={2,3,4679,35617};LL fac[4][36666],c[4],N,G,blk; //懶得寫質因數分解..(而且可能能避免一些麻煩??)
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;}
LL qpow(LL a,LL b,LL p,LL s=1
){for(;b;b>>=1,a=a*a%p)if(b&1)s=s*a%p;return s;} LL inv(LL a,LL b,LL x=0,LL y=0){if(!a)return 0;exgcd(a,b,x,y);return(x%b+b)%b;} void calcfac(){for(int i=0;i<4;++i){fac[i][0]=1;for(int j=1;j<=pr[i];++j)fac[i][j]=fac[i][j-1]*j%pr[i];}} //預處理階乘 LL C(LL n,LL m,LL p,LL x=0){if(n<m) return 0; x=pr[p];return fac[p][n]*inv(fac[p][m],x)%x*inv(fac[p][n-m],x)%x;} //計算小於第p個質數的組合數 LL lucas(LL n,LL m,LL p,LL x=0){if(!m) return 1; x=pr[p];return C(n%x,m%x,p)*lucas(n/x,m/x,p)%x;} //基礎的Lucas定理 LL CRT(LL x=0,LL y=0,LL ans=0){for(int i=0;i<4;++i)ans=(ans+c[i]*(P/pr[i])%P*inv(P/pr[i],pr[i])%P)%P;return ans;} //中國剩余定理辣~ void ANS(){for(int i=1;i<=blk;++i)if(N%i==0){for(int j=0;j<4;++j){if(i*i!=N) c[j]=(c[j]+lucas(N,i,j))%pr[j];c[j]=(c[j]+lucas(N,N/i,j))%pr[j];}}} //預處理階乘對各個質數取模的答案(就是式子裏的c1..c4) int main(){scanf("%lld%lld",&N,&G);G%=P;if(!G){puts("0");return 0;}blk=sqrt(N);calcfac();ANS();printf("%lld",qpow(G,CRT(),P+1));}

我怎麽會說註意事項

  • 沒有\(p_i^{k_i}\)這樣的項就不需要擴展Lucas了...
  • 階乘處理的時候一定記得從0開始處理..
  • 枚舉k的時候只需從\(1\sim \sqrt n\)枚舉, \(k|n\)就直接把\(C_{n}^{k}\)\(C_{n}^{\frac{n}{k}}\)一起算了..(\(1\sim n\)枚舉我猜會T飛→_→
  • 其實數論題全開long long好像是個不錯的主意OvO...
  • 好像是有邊界數據要特判來著...(見下)

95才能看的邊界數據

#13出鍋? 看這裏!!!
P.S. 這組數據是我從luogu上交4遍分別輸出\(N\ N\%10000\ G\ G\%10000\)摳出來的...
| 輸入 | 輸出 |
|-|-|
| 999911657 999911659 | 0 |
要是不加特判直接做會輸出1 就WA了...
其實我第一遍WA意識到要加特判但是加錯了OvO
(你可以看到我代碼裏的\(P\)是多少然後你應該能猜到出了什麽問題→_→

這個部分真啥都沒有

其實就是啥都沒有...完結撒花~

【學術篇】SDOI2010 古代豬文