UOJ#269. 【清华集训2016】如何优雅地求和(FFT)

传送门

题解:
f f 二项式变换一下就行了,变换可以用二项式反演。

#include <bits/stdc++.h>
using namespace std;

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=2e5+50, mod=998244353;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
inline int cinv(int a) {return power(a,mod-2);}

int n,m,k,x,a[N],b[N],w[N],pos[N];
struct combin {
	int fac[N],ifac[N],dn[N];
	inline void init() {
		fac[0]=1;
		for(int i=1;i<=m;i++) fac[i]=mul(fac[i-1],i);
		ifac[m]=cinv(fac[m]);
		for(int i=m-1;~i;i--) ifac[i]=mul(ifac[i+1],i+1);
		dn[0]=1;
		for(int i=1;i<=m;i++) dn[i]=mul(dn[i-1],dec(n+1,i)), dn[i]=mul(dn[i],cinv(i));
	}
} C;
inline void init(int nn) {
	for(k=1;k<=nn;k<<=1);
	for(int i=1;i<k;i++) pos[i]=(i&1) ? ((pos[i>>1]>>1)^(k>>1)) : (pos[i>>1]>>1);
}
inline void dft(int *A,int o=1) {
	for(int i=1;i<k;i++) if(pos[i]>i) swap(A[i],A[pos[i]]);
	for(int bl=1;bl<k;bl<<=1) {
		int tl=bl<<1, wn=power(3,(mod-1)/tl);
		w[0]=1; for(int i=1;i<bl;i++) w[i]=mul(w[i-1],wn);
		for(int bg=0;bg<k;bg+=tl)
			for(int j=0;j<bl;j++) {
				int &t1=A[bg+j], &t2=A[bg+j+bl], t=mul(t2,w[j]);
				t2=dec(t1,t); t1=add(t1,t);
			}
	} 
	if(!~o) {
		const int inv=cinv(k);
		for(int i=0;i<k;i++) a[i]=mul(a[i],inv);
		reverse(a+1,a+k);
	}
}
int main() {
	n=rd(), m=rd(), x=rd();
	C.init();
	for(int i=0;i<=m;i++) b[i]=mul(rd(),C.ifac[i]);
	for(int i=0;i<=m;i++) a[i]=mul((i&1)?mod-1:1,C.ifac[i]);
	init(m*2); dft(a); dft(b);
	for(int i=0;i<k;i++) a[i]=mul(a[i],b[i]);
	dft(a,-1); 
	for(int i=0;i<=m;i++) a[i]=mul(a[i],C.fac[i]);
	int ans=0;
	for(int i=0,v=1;i<=m;i++)
		ans=add(ans,mul(C.dn[i],mul(a[i],v))), v=mul(v,x);
	cout<<ans<<'\n';
}
发布了553 篇原创文章 · 获赞 227 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_35649707/article/details/83656631
今日推荐