前置知识单位根反演自己去浅谈单位根反演看
看到这个式子很自然地想到算贡献啊,考虑对于每个(a_i(iin[0,3]))求出下标(mod 4=i)的点值和即可
因此我们现在答案的式子就是:
[sum_{i=0}^3 a_icdot sum_{j=0}^n [jmod 4=i] C_n^jcdot s^j
]
题目名都告诉你了要用二项式定理,因此令:
[F(x)=sum_{i=0}^n C_n^icdot s^i x^i=sum_{i=0}^n (sx+1)^n
]
先求(a_0)的贡献。对前面的那个式子用单位根反演带进去
[sum_{j=0}^n [jmod i=0] C_n^jcdot s^j
]
[=sum_{j=0}^nC_n^jcdot s^jsum_{k=0}^3 omega_4^{jk}=sum_{j=0}^3F(w_4^j)
]
然后(a_i(iin [1,3]))怎么办,直接按最前面博客里讲的那样把多项式平移即可!
然后做完了,复杂度(O(4^2cdot Tlog n))
#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=5,mod=998244353;
int t,s,g,a[5],w[N],ans; long long n;
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void inc(int& x,CI y)
{
if ((x+=y)>=mod) x-=mod;
}
int main()
{
RI i,j; for (g=quick_pow(3,(mod-1)/4),w[0]=i=1;i<4;++i)
w[i]=1LL*w[i-1]*g%mod; for (scanf("%d",&t);t;--t)
{
for (scanf("%lld%d",&n,&s),i=0;i<4;++i) scanf("%d",&a[i]);
int ret; for (ans=0,i=0;i<4;++i)
{
for (ret=j=0;j<4;++j) inc(ret,1LL*quick_pow((1LL*s*w[j]+1)%mod,n%(mod-1))*quick_pow(w[i*j%4])%mod);
inc(ans,1LL*ret*quick_pow(4)%mod*a[i]%mod);
}
printf("%d
",ans);
}
}