Loj#6247. 九个太阳
题解
前置知识
原根
二项式定理
单位根
题目
给定 n,K,满足K 是 2 的幂,求
K∣i,0≤i≤n∑(in)
对 998244353 取模 。
1≤n≤1015,1≤K≤220 , 且 K 为2 的幂 。
思路
首先将式子写为 :
i=0∑n(in)[K∣i]
然后观察式子中的条件🤔 ,可以用单位根反演 :
n1i=0∑n−1ωnx∗i=[xmodn=0]
化简式子为 :
i=0∑n(in)[K∣i]=i=0∑nK1j=0∑K−1ωni∗j(in)=K1i=1∑nj=0∑K−1ωni∗j(in)=K1j=0∑K−1i=0∑n(ωnj)i(in)
然后观察后面的式子,对其使用二项式定理!
(a+b)n=i=0∑n(in)aibn−i
拆分为 :
K1j=0∑K−1i=0∑n(ωnj)i(in)=K1j=0∑K−1(1+ωnj)n
计算时由于 998244353=223×17×7+1 刚好存在原根 3
998244353最优美的性质莫过于它是个完美恶臭数:998244353=( 114514 * ( 54-1+114 * (1+14*5+1+4) ) ) + ( 4+11451 * (4-1-15+14) ) + ( 11+41*54 + (141+541) ) + (4-1-15+14);之所以称为完美,如果您仔细观察,您会发现每一个括号里114514都出现了正整数次!
将 ωn 设为 3Kp−1 即可
时间复杂度 O(nlogn)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<bits/stdc++.h> #define ll long long using namespace std; const int mod=998244353; ll ans; ll qpow(ll a,ll b,ll mod) { ll t=1; while(b!=0) { if(b&1)t=(t*a)%mod; a=(a*a)%mod;b>>=1; } return t; } ll inv(ll x){return (qpow(x,mod-2,mod)+mod)%mod;} int main() { ll n,k; scanf("%lld%lld",&n,&k); ll wn=qpow(3,(mod-1)/k,mod); for(ll i=0,c=1;i<k;i++,c=c*wn%mod) { ans=(ans+qpow(1+c,n,mod))%mod; } printf("%lld",(ans*inv(k)%mod+mod)%mod); return 0; }
|