其他分享
首页 > 其他分享> > P5641. 【CSGRound2】开拓者的卓识

P5641. 【CSGRound2】开拓者的卓识

作者:互联网

\(\text{Solution}\)

推柿子比较套路,考虑每一个\(a_i\)对\(sum_{k,1,j}\)的贡献即可。
看看\(sum\)是如何转移的

\[a_i \implies sum_{1,l_1,r_1} \implies sum_{2,l_2,r_2} \implies ... \implies sum_{k,l_k,r_k} \]

其中\(1 \le l_k \le l_{k - 1} \le ... \le i \le ... \le r_k \le j\)
那我们只需考虑\(l,r\)组合的方案数即可,用插板法计算为

\[\binom{i + k - 2}{k - 1}\binom{j - i + k - 1}{k - 1} \]

所以

\[sum_{k,1,j} = \sum_{i = 1}^{j}a_i\binom{i + k - 2}{k - 1}\binom{j - i + k - 1}{k - 1} \]

\[A_i = a_{i}\binom{i + k - 2}{k - 1} = \frac{a_ik^{\overline{i - 1}}}{(i - 1)!},B_i = \binom{i + k - 1}{k - 1} = \frac{k^{\overline{i}}}{i!} \]

这样可以快速计算\(A_i,B_i\)。

\[sum_{k,1,j} = \sum_{i + (j - i) = j}A_iB_{j - i} \]

这样就是卷积了。

\(\text{Code}\)

#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
const int N = 1e5 + 5,P = 998244353;
int n,rev[N * 3]; LL k,a[N],b[N],f[N * 3],g[N * 3];

LL fpow(LL x,LL y)
{
	LL res = 1;
	for (; x; x >>= 1,y = y * y % P)
		if (x & 1) res = res * y % P;
	return res;	
}
void NTT(LL *f,int len,int fl)
{
	if (len == 1) return;
	for (int i = 0; i < len; i++)
		if (i < rev[i]) swap(f[i],f[rev[i]]);
	for (int l = 1; l < len; l <<= 1)
	{
		LL I = fpow((P - 1) / (l << 1),3);
		if (fl == -1) I = fpow(P - 2,I);
		for (int i = 0; i < len; i += (l << 1))
		{
			LL W = 1;
			for (int j = 0; j < l; j++,W = W * I % P)
			{
				LL x = f[i + j],y = W * f[i + j + l] % P;
				f[i + j] = (x + y) % P,f[i + j + l] = (x - y + P) % P;
			}
		}
	}
}
int main()
{
	scanf("%d%lld",&n,&k);
	for (int i = 1; i <= n; i++) scanf("%lld",&a[i]);
	b[0] = 1;
	for (int i = 1; i <= n; i++) b[i] = b[i - 1] * (k + i - 1) % P * fpow(P - 2,i) % P;
	for (int i = 1; i <= n; i++) f[i] = a[i] * b[i - 1] % P;
	for (int i = 1; i <= n; i++) g[i] = b[i]; g[0] = 1;
	
	int len = 1,bit = 0;
	while (len <= n << 1) len <<= 1,bit++;
	for (int i = 1; i < len; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << bit - 1);
	
	NTT(f,len,1),NTT(g,len,1);
	for (int i = 0; i < len; i++) f[i] = f[i] * g[i] % P;
	NTT(f,len,-1); LL inv = fpow(P - 2,len);
	for (int i = 1; i <= n; i++) printf("%lld ",inv * f[i] % P); 
} 

标签:le,res,int,P5641,CSGRound2,卓识,sum,binom,LL
来源: https://www.cnblogs.com/nibabadeboke/p/16478383.html