Loj#6247-九個太陽【單位根反演】
阿新 • • 發佈:2021-06-29
正題
題目大意
給出\(n,k\)求
\[\sum_{0\leq i\leq n,i|k}\binom{n}{i} \]對\(998244353\)取模
\(1\leq n\leq 10^{15},1\leq k\leq 2^{20},k=2^p(p\in N)\)
解題思路
隨便找的一題竟然是單位根反演,不過很基礎而且很裸。
首先單位根反演的式子\([i|k]=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{i\times j}\)
然後帶到這題的式子就是
\[\sum_{i=0}^n\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{i\times j}\binom{n}{i} \]然後把\(j\)
然後二項式定理
\[\frac{1}{k}\sum_{j=0}^{k-1}(\omega_k^{i}+1)^n \]額但是\(n\)很大直接用複數精度肯定會炸,但是\(998244353-1=2^{23}\times 7\times 17\)...又因為\(k=2^p\),其實就是類似於\(NTT\)的思路我們直接用原根\(\omega_k^1=g^{\frac{P-1}{k}}\)就好了。
時間複雜度\(O(k\log n)\)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll P=998244353; ll n,k,ans; ll power(ll x,ll b){ ll ans=1; while(b){ if(b&1)ans=ans*x%P; x=x*x%P;b>>=1; } return ans; } signed main() { scanf("%lld%lld",&n,&k); ll g=power(3,(P-1)/k),z=1; for(ll i=0;i<k;i++,z=z*g%P) (ans+=power(z+1,n)%P)%=P; printf("%lld\n",ans*power(k,P-2)%P); return 0; }