luogu P3711 仓鼠的数学题

18 篇文章 0 订阅
2 篇文章 1 订阅

背景:

发现自己推公式的能力好差。

题目传送门:

https://www.luogu.org/problemnew/show/P3711

题意:

∑ k = 0 n a k ∑ i = 0 x i k \sum_{k=0}^{n}a_k\sum_{i=0}^{x}i^k k=0naki=0xik的每一项的系数。
你不需要管 x x x是什么,毒瘤出题人就是让你不不知道某些知识读不懂题。

思路:

大力推式子。
∑ k = 0 n a k ∑ i = 0 x i k \sum_{k=0}^{n}a_k\sum_{i=0}^{x}i^k k=0naki=0xik
考虑伯努利数,带入 ∑ i = 0 x i k = 0 k + x k + ∑ i = 1 x − 1 i k = x k + ∑ i = 1 x − 1 = x k + 1 k + 1 ∑ i = 1 k + 1 C k + 1 i ⋅ B k + 1 − i ⋅ ( x − 1 + 1 ) i = x k + 1 k + 1 ∑ i = 1 k + 1 C k + 1 i ⋅ B k + 1 − i ⋅ x i \sum_{i=0}^{x}i^k=0^k+x^k+\sum_{i=1}^{x-1}i^k=x^k+\sum_{i=1}^{x-1}=x^k+\frac{1}{k+1}\sum_{i=1}^{k+1}C_{k+1}^{i}\cdot B_{k+1-i}\cdot (x-1+1)^i=x^k+\frac{1}{k+1}\sum_{i=1}^{k+1}C_{k+1}^{i}\cdot B_{k+1-i}\cdot x^i i=0xik=0k+xk+i=1x1ik=xk+i=1x1=xk+k+11i=1k+1Ck+1iBk+1i(x1+1)i=xk+k+11i=1k+1Ck+1iBk+1ixi有:
= ∑ k = 0 n a k ( x k + 1 k + 1 ∑ i = 1 k + 1 C k + 1 i ⋅ B k + 1 − i ⋅ x i ) =\sum_{k=0}^{n}a_k\big(x^k+\frac{1}{k+1}\sum_{i=1}^{k+1}C_{k+1}^{i}\cdot B_{k+1-i}\cdot x^i\big) =k=0nak(xk+k+11i=1k+1Ck+1iBk+1ixi)

考虑 C C C是有对称性的,因此有:
= ∑ k = 0 n a k ( x k + 1 k + 1 ∑ i = 0 k C k + 1 i ⋅ B i ⋅ x k + 1 − i ) = ∑ k = 0 n a k ( x k + 1 k + 1 ∑ i = 0 k ( k + 1 ) ! i ! ( k + 1 − i ) ! ⋅ B i ⋅ x k + 1 − i ) \begin{aligned}&=\sum_{k=0}^{n}a_k\big(x^k+\frac{1}{k+1}\sum_{i=0}^{k}C_{k+1}^{i}\cdot B_{i}\cdot x^{k+1-i}\big)\\ &=\sum_{k=0}^{n}a_k\big(x^k+\frac{1}{k+1}\sum_{i=0}^{k}\frac{(k+1)!}{i!(k+1-i)!}\cdot B_{i}\cdot x^{k+1-i}\big)\end{aligned} =k=0nak(xk+k+11i=0kCk+1iBixk+1i)=k=0nak(xk+k+11i=0ki!(k+1i)!(k+1)!Bixk+1i)

抵消 k + 1 k+1 k+1,得:
= ∑ k = 0 n a k ( x k + ∑ i = 1 k + 1 k ! i ! ( k + 1 − i ) ! ⋅ B i ⋅ x k + 1 − i ) = ∑ k = 0 n a k x k + ∑ k = 0 n ∑ i = 0 k a k k ! i ! ( k + 1 − i ) ! ⋅ B i ⋅ x k + 1 − i \begin{aligned}&=\sum_{k=0}^{n}a_k\big(x^k+\sum_{i=1}^{k+1}\frac{k!}{i!(k+1-i)!}\cdot B_{i}\cdot x^{k+1-i}\big)\\ &=\sum_{k=0}^{n}a_kx^k+\sum_{k=0}^{n}\sum_{i=0}^{k}a_k\frac{k!}{i!(k+1-i)!}\cdot B_{i}\cdot x^{k+1-i}\end{aligned} =k=0nak(xk+i=1k+1i!(k+1i)!k!Bixk+1i)=k=0nakxk+k=0ni=0kaki!(k+1i)!k!Bixk+1i

d = k + 1 − i d=k+1-i d=k+1i,有:
= ∑ d = 0 n a d x d + ∑ d = 1 n + 1 ∑ k = d − 1 n a k k ! ( k + 1 − d ) ! d ! ⋅ B k + 1 − d ⋅ x d =\sum_{d=0}^{n}a_dx^d+\sum_{d=1}^{n+1}\sum_{k=d-1}^{n}a_{k}\frac{k!}{(k+1-d)!d!}\cdot B_{k+1-d}\cdot x^{d} =d=0nadxd+d=1n+1k=d1nak(k+1d)!d!k!Bk+1dxd

f i = a i ⋅ i ! , g = B k + 1 − d ( k + 1 − d ) ! f_i=a_i\cdot i!,g=\frac{B_{k+1-d}}{(k+1-d)!} fi=aii!,g=(k+1d)!Bk+1d所以有:
= ∑ d = 1 n + 1 a d x d + ∑ d = 0 n ∑ k = d − 1 n f k g k + 1 − d d ! ⋅ x d = ∑ d = 1 n + 1 a d x d + ∑ d = 0 n 1 d ! ⋅ x d ∑ k = d − 1 n f k g k + 1 − d \begin{aligned}&=\sum_{d=1}^{n+1}a_dx^d+\sum_{d=0}^{n}\sum_{k=d-1}^{n}\frac{f_kg_{k+1-d}}{d!}\cdot x^{d}\\ &=\sum_{d=1}^{n+1}a_dx^d+\sum_{d=0}^{n}{\frac{1}{d!}}\cdot x^{d}\sum_{k=d-1}^{n}f_kg_{k+1-d}\end{aligned} =d=1n+1adxd+d=0nk=d1nd!fkgk+1dxd=d=1n+1adxd+d=0nd!1xdk=d1nfkgk+1d

h i = g n − i h_i=g_{n-i} hi=gni,则有: g k + 1 − d = h n − ( k + 1 − d ) = h n − k + d − 1 g_{k+1-d}=h_{n-(k+1-d)}=h_{n-k+d-1} gk+1d=hn(k+1d)=hnk+d1,即:
= ∑ d = 1 n + 1 a d x d + ∑ d = 0 n 1 d ! ⋅ x d ∑ k = d − 1 n f k h n − k + d − 1 =\sum_{d=1}^{n+1}a_dx^d+\sum_{d=0}^{n}{\frac{1}{d!}}\cdot x^{d}\sum_{k=d-1}^{n}f_kh_{n-k+d-1} =d=1n+1adxd+d=0nd!1xdk=d1nfkhnk+d1

发现后面是一个卷积的形式,最高项的次数为 k + ( n − k + d − 1 ) = n + d − 1 k+(n-k+d-1)=n+d-1 k+(nk+d1)=n+d1,用第 n + d − 1 n+d-1 n+d1的系数乘上 1 d ! \frac{1}{d!} d!1,最后加上 a k a_k ak即可。
特别地: a n s 0 = a 0 ans_0=a_0 ans0=a0 0 0 = 1 0^0=1 00=1)。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef long double LD;
const int mod=998244353,G=3,inv_G=332748118;
	int r[2000010],A[2000010],a[2000010],b[2000010],f[2000010],g[2000010];
	int fac[2000010],Inv[2000010],B[2000010];
	int limit,n,l;
	LL sum;
int dg(int x,int k)
{
	if(!k) return 1;
	int op=dg(x,(k>>1));
	if(k&1) return (LL)op*op%mod*x%mod; else return (LL)op*op%mod;
}
int inv(int x)
{
	return dg(x,mod-2);
}
void NTT(int *now,int limit,int op)
{
	for(int i=0;i<limit;i++)
		if(i<r[i]) swap(now[i],now[r[i]]);
	for(int mid=1;mid<limit;mid<<=1)
	{
		int wn=dg(op==1?G:inv_G,(mod-1)/(mid<<1));
		for(int j=0;j<limit;j+=(mid<<1))
		{
			int w=1;
			for(int k=0;k<mid;k++,w=(int)(((LL)w*wn)%mod))
			{
				LL x=now[j+k],y=(LL)w*now[j+k+mid]%mod;
				now[j+k]=((LL)x+y)%mod;
				now[j+k+mid]=((LL)x-y+mod)%mod;
			}
		}
	}
}
void init(int n)
{
	limit=1,l=0;
	while(limit<(n<<1))
		limit<<=1,l++;
	for(int i=1;i<limit;i++)
		r[i]=((r[i>>1]>>1)|((i&1)<<(l-1)));
}
void dft(int *f,int n,int limit)
{
	NTT(f,limit,-1);
	int INV=inv(limit);
	for(int i=0;i<limit;i++)
		f[i]=(LL)f[i]*INV%mod;
}
void poly_inv(int *f,int *g,int n)
{
	if(n==1)
	{
		g[0]=inv(f[0]);
		return;
	}
	poly_inv(f,g,(n+1)>>1);
	init(n);
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	for(int i=0;i<n;i++)
		a[i]=f[i],b[i]=g[i];
	NTT(a,limit,1),NTT(b,limit,1);
	for(int i=0;i<limit;i++)
		b[i]=(LL)b[i]*((2ll-(LL)a[i]*b[i]%mod+mod)%mod)%mod;
	dft(b,n,limit);
	for(int i=0;i<n;i++)
		g[i]=b[i];
}
void INIT(int n)
{
	fac[0]=fac[1]=1;
	Inv[0]=Inv[1]=1;
	for(int i=2;i<=n;i++)
	{
		fac[i]=(LL)fac[i-1]*i%mod;
		Inv[i]=((LL)mod-mod/i)*Inv[mod%i]%mod;
	}
	for(int i=2;i<=n;i++)
		Inv[i]=(LL)Inv[i-1]*Inv[i]%mod;
	for(int i=0;i<=n;i++)
		f[i]=Inv[i+1];
	poly_inv(f,g,n);
	for(int i=0;i<=n;i++)
		B[i]=(LL)g[i]*fac[i]%mod;
}
int calc_C(int n,int m)
{
	return (LL)fac[n]*Inv[n-m]%mod*Inv[m]%mod;
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<=n;i++)
		scanf("%d",&A[i]);
	init(n);
	INIT(limit);
	for(int i=0;i<=n;i++)
	{
		f[i]=(LL)A[i]*fac[i]%mod;
		g[n-i]=(LL)B[i]*Inv[i]%mod;
	}
	init(n+1);
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	for(int i=0;i<=n;i++)
		a[i]=f[i],b[i]=g[i];
	NTT(a,limit,1),NTT(b,limit,1);
	for(int i=0;i<limit;i++)
		a[i]=(LL)a[i]*b[i]%mod;
	dft(a,n+1,limit);
	for(int i=0;i<=limit;i++)
		g[i]=a[i];
	printf("%d",A[0]);
	for(int d=1;d<=n+1;d++)
		printf(" %d",((LL)A[d]+(LL)Inv[d]*g[n+d-1]%mod)%mod);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值