其他分享
首页 > 其他分享> > 仓鼠的数学题

仓鼠的数学题

作者:互联网

题意

求\(\sum\limits_{k=0}^nS_k(x)\)这个多项式的每一项。

思路

直接代入伯努利数推柿子:
\(\sum\limits_{k=0}^n(S_k(x)+x^k)\)
\(=\sum\limits_{k=0}^na_kx^k+\sum\limits_{k=0}^na_kS_k(x)\)
\(=\sum\limits_{k=0}^na_kx^k+\frac{1}{k+1}\sum\limits_{j=0}^k\binom{k+1}{j}B_jx^{k+1-j}a_k\)
\(=\sum\limits_{k=0}^na_kx^k+\sum\limits_{k=0}^nk!a_k \sum\limits_{j=0}^k\frac{B_j}{j!}(k+1-j)!x^{k+1-j}\)
不妨令\(F(x)=x!a_x\),\(G(x)=\frac{B_x}{x!}\)
答案\(x^n\)的系数为:
\(=a_n+\sum\limits_{k=0}^n \sum\limits_{j=0}^k F(k)G(j)[k+1-j=n]\)
当然实际推的时候我还是先把\(x\)次项提到前面来的,这是差卷积的形式,翻转F/G即可。

code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int mod=998244353;
ll ksm(ll a,ll b) {ll mul=1;for(;b;b>>=1,a=a*a%mod)if(b&1)mul=mul*a%mod;return mul;}
const int inv3=ksm(3,mod-2);
ll jc[N],ijc[N],inv[N];

ll binom(int n,int m) {return (n<m)?0:jc[n]*ijc[m]%mod*ijc[n-m]%mod;}

int up,L,rev[N];
ll gen[2][N];
void gt_up(int n) {
	up=1;L=0;
	while(up<=n) {up<<=1,L++;}
	for(int i=1;i<up;i++) {rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));}
}

void _clr(int n,ll *f) {for(int i=n;i<up;i++)f[i]=0;}
void _clr2(int n,ll *f,ll *g) {for(int i=n;i<up;i++)f[i]=g[i]=0;}

void gt_gen(int n) {
	gt_up(n);
	gen[0][up]=ksm(3,(mod-1)/up);gen[1][up]=ksm(inv3,(mod-1)/up);
	for(int i=up;i;i>>=1) {
		gen[0][i>>1]=gen[0][i]*gen[0][i]%mod;
		gen[1][i>>1]=gen[1][i]*gen[1][i]%mod;
	}
}
void init(int n) {
	jc[0]=1;for(int i=1;i<=n;i++)jc[i]=jc[i-1]*i%mod;
	ijc[n]=ksm(jc[n],mod-2);for(int i=n;i;i--)ijc[i-1]=ijc[i]*i%mod;
}

void NTT(ll *a,int op) {
	for(int i=0;i<up;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
	for(int mid=1;mid<up;mid<<=1) {
		int len=mid<<1;ll w1=gen[op][len];
		for(int i=0;i<up;i+=len) {
			ll w=1;
			for(int j=0;j<mid;j++,w=w*w1%mod) {
				int p=i+j,q=p+mid;
				ll x=a[p],y=a[q]*w;
				a[p]=(x+y)%mod,a[q]=(x-y)%mod;
			}
		}
	}
}

ll t[N];
void poly_inv(int n,ll *f,ll *b) {
//	printf("*%d\n",n);
	if(n==1) {b[0]=ksm(f[0],mod-2);return;}
	poly_inv((n+1)>>1,f,b);
	gt_up(n<<1);
	for(int i=0;i<n;i++)t[i]=f[i];_clr(n,t);
	NTT(t,0),NTT(b,0);
	for(int i=0;i<up;i++)b[i]=(2-t[i]*b[i])%mod*b[i]%mod;
	NTT(b,1);
	for(int i=0,j=ksm(up,mod-2);i<n;i++)b[i]=b[i]*j%mod;_clr(n,b);
}

ll a[N],B[N],F[N],G[N];
int main() {
//	freopen("data.in","r",stdin);
	int n;scanf("%d",&n);n++;
	gt_gen((n+1)<<1);init(n);
	for(int i=0;i<n;i++) {scanf("%d",&a[i]);}
	for(int i=0;i<n;i++) F[i]=ijc[i+1];	//左移一位
	poly_inv(n,F,B);
	gt_up((n+1)<<1);
	for(int i=0;i<n;i++) F[i]=a[i]*jc[i]%mod,G[n-1-i]=B[i]%mod;
	_clr(n+1,F);
	NTT(F,0),NTT(G,0);
	
	for(int i=0;i<up;i++)F[i]=F[i]*G[i]%mod;
	NTT(F,1);
	printf("%lld ",a[0]);
	for(int i=1,j=ksm(up,mod-2);i<=n;i++) {
		ll ans=F[n+i-2]*j%mod*ijc[i]%mod;
		printf("%lld ",(ans+a[i]+mod)%mod);
	}
	return 0;
}

标签:limits,int,sum,gen,数学题,仓鼠,ll,mod
来源: https://www.cnblogs.com/bestime/p/16510491.html