LOJ #6485. LJJ 学二项式定理

前置知识单位根反演自己去浅谈单位根反演

看到这个式子很自然地想到算贡献啊,考虑对于每个\(a_i(i\in[0,3])\)求出下标\(\mod 4=i\)的点值和即可

因此我们现在答案的式子就是:

\[\sum_{i=0}^3 a_i\cdot \sum_{j=0}^n [j\mod 4=i] C_n^j\cdot s^j \]

题目名都告诉你了要用二项式定理,因此令:

\[F(x)=\sum_{i=0}^n C_n^i\cdot s^i x^i=\sum_{i=0}^n (sx+1)^n \]

先求\(a_0\)的贡献。对前面的那个式子用单位根反演带进去

\[\sum_{j=0}^n [j\mod i=0] C_n^j\cdot s^j \]

\[=\sum_{j=0}^nC_n^j\cdot s^j\sum_{k=0}^3 \omega_4^{jk}=\sum_{j=0}^3F(w_4^j) \]

然后\(a_i(i\in [1,3])\)怎么办,直接按最前面博客里讲的那样把多项式平移即可!

然后做完了,复杂度\(O(4^2\cdot T\log 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\n",ans);
	}
}
posted @ 2019-10-23 16:01  空気力学の詩  阅读(423)  评论(0编辑  收藏  举报