题目
[largesum_{i=0}^nC(n,i)S^ia_{imod 4}
]
(nleq 10^{18},S,aleq 10^8)
分析
前面这一坨看起来就像是二项式定理,考虑如何把后面这一坨弄掉
[large=sum_{i=0}^nC(n,i)S^isum_{j=0}^3a_j[imod 4==j]
]
由于([imod 4==j])等同于([4|(i-j)])
[large=frac{1}{4}sum_{i=0}^nC(n,i)S^isum_{j=0}^3a_jsum_{k=0}^3omega_4^{k(i-j)}
]
把有关(j)的项挪到前面去,就是
[large=frac{1}{4}sum_{j=0}^3a_jsum_{k=0}^3-omega_4^{jk}sum_{i=0}^nC(n,i)S^iomega_4^{ki}
]
[large=frac{1}{4}sum_{j=0}^3a_jsum_{k=0}^3-omega_4^{jk}(Somega_4^k+1)^n
]
直接预处理单位根就可以了
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int mod=998244353; int pw[4];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
signed main(){
pw[0]=1,pw[1]=ksm(3,(mod-1)/4);
for (rr int i=2;i<4;++i)
pw[i]=1ll*pw[i-1]*pw[1]%mod;
rr int inv4=ksm(4,mod-2);
for (rr int T=iut();T;--T){
rr long long n; scanf("%lld",&n);
n%=mod-1; rr int m=iut(),ans=0;
for (rr int i=0;i<4;++i){
rr int x=iut(),sum=0;
for (rr int j=0;j<4;++j)
sum=mo(sum,1ll*pw[(4-i*j%4)%4]*ksm(1ll*m*pw[j]%mod+1,n)%mod);
ans=mo(ans,1ll*sum*x%mod);
}
print(1ll*ans*inv4%mod),putchar(10);
}
return 0;
}