也许更好的阅读体验
Description
原题链接
T组询问,每次给 n,s,a0,a1,a2,a3求
(i=0∑n(ni)⋅si⋅ai mod 4)mod 998244353
Solution
这道题要用单位根反演
[n ∣ k]=n1i=0∑n−1wnik
我们先打表,或者查表找出在模 998244353下的原根 ω40并处理好 ω41,ω42,ω43
考虑对每个 ai单独计算其答案
以 a0为例
ansa0=41a0i=0∑n[4 ∣ i](in)si=41a0i=0∑n(in)sij=0∑3(ω4j)i=41a0j=0∑3i=0∑n(in)si(ω4j)i=41a0j=0∑3(sω4j+1)n
对于其他 ai,我们可以将其写成 [4 ∣ i+4−k]的形式,并提一个 ωx出来
下面完整的推一遍
ans=k=0∑3aki=0∑n[4 ∣ i+4−k]si⋅(ni)=k=0∑341aki=0∑nj=0∑3ω4j⋅(i+4−k)⋅si⋅(ni)=k=0∑341aki=0∑nj=0∑3ω4(4j−jk)⋅ω4ji⋅si⋅(ni)=k=0∑341akj=0∑3ω4(4j−jk)i=0∑nωji⋅si⋅(ni)=k=0∑341akj=0∑3ω4(4j−jk)(s⋅ω4j+1)n
拿出来,再写一遍
ans=i=0∑341aij=0∑3ω4(4j−ij)(s⋅ω4j+1)n
Code
#include <cstdio>
#define ll long long
using namespace std;
const int mod = 998244353;
const int w [] = {1,911660635,998244352,86583718};
ll T,n,s,ans,res,inv;
ll a[4];
ll ksm (ll a,ll b)
{
a%=mod;
ll s=1;
for (;b;b>>=1,a=a*a%mod)
if (b&1) s=s*a%mod;
return s;
}
int main ()
{
scanf("%lld",&T);
inv=ksm(4,mod-2);
while (T--){
scanf("%lld%lld%lld%lld%lld%lld",&n,&s,&a[0],&a[1],&a[2],&a[3]);
ans=0;
for (int i=0;i<=3;++i){
res=0;
for (int j=0;j<=3;++j)
res=(res+w[(4*j-i*j)%4]*ksm(s*w[j]+1,n)%mod)%mod;
ans=(ans+a[i]*res%mod)%mod;
}
printf("%lld\n",ans*inv%mod);
}
return 0;
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧