( ext{Solution:})
观察到这个东西的下标是带 (mod) 的,而且组合数的形式很像二项式定理。考虑单位根反演把下标的 (mod 4) 去掉。
[sum_{i=0}^n inom{n}{i}s^ia_{imod 4}
\
=sum_{i=0}^n inom{n}{i}s^isum_{j=0}^3 a_j[jequiv i(mod 4)]
\
=sum_{i=0}^n inom{n}{i}s^isum_{j=0}^3 a_j[4|(i-j)]
\
=sum_{i=0}^n inom{n}{i}s^isum_{j=0}^3 a_jfrac{1}{4}sum_{k=0}^3 omega_{4}^{k(i-j)}
\
=frac{1}{4}sum_{j=0}^3 a_jsum_{k=0}^3 omega_{4}^{-kj}sum_{i=0}^n inom{n}{i}s^i omega_4^{ki}
\
=frac{1}{4}sum_{j=0}^3 a_jsum_{k=0}^3 omega_{4}^{-kj}(somega_4^k+1)^n
]
观察到在 (mod 998244353) 下,其 (4) 次单位根是存在的,原根为 (3,) 又因为 (a^{mod-1}equiv 1(mod mod),) 故而 (omega_4=g^{frac{mod-1}{4}})
注意到指数上是整除的,所以存在。
于是单次计算就可以 (O(log n)) 了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int g=3;
inline int Add(int x,int y){return (x+y)%mod;}
inline int Mul(int x,int y){return 1ll*x*y%mod;}
inline int qpow(int x,int y){
int res=1;
while(y){
if(y&1)res=Mul(res,x);
x=Mul(x,x);y>>=1;
}
return res;
}
int T,n,s,a[4],Pw[50];
inline int getinv(int x){return qpow(x,mod-2);}
signed main(){
scanf("%lld",&T);
int W=qpow(3,(mod-1)/4);
Pw[0]=1;
for(int i=1;i<=20;++i)Pw[i]=Mul(Pw[i-1],W);
while(T--){
scanf("%lld%lld",&n,&s);
for(int i=0;i<4;++i)scanf("%lld",&a[i]);
int ans=0;
for(int i=0;i<4;++i){
int sum=0;
for(int j=0;j<4;++j){
int wn=getinv(Pw[i*j]);
int swk=Mul(s,qpow(W,j));
int spw=qpow(swk+1,n);
sum=Add(sum,Mul(wn,spw));
}
ans=Add(ans,Mul(a[i],sum));
}
ans=Mul(ans,getinv(4));
printf("%lld
",ans);
}
return 0;
}