1. 程式人生 > >2017 多小訓練第三場 HDU 6061 RXD and functions

2017 多小訓練第三場 HDU 6061 RXD and functions

NTT

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int maxn=4e5+5;
const int g=3;
ll ni[maxn],fro[maxn],K[maxn],qp[30],F1[maxn],F2[maxn],ans[maxn];

int getlen(int a){
	a<<=1;
	int ans=1;
	while(ans<a) ans<<=1;
	return ans;
}

ll qpow(ll a,ll b){
	a%=mod;
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}

void init(){
	for(int i=0;i<21;i++){
		int t=1<<i;
		qp[i]=qpow(g,(mod-1)/t);
	}
	fro[0]=ni[0]=1;
	for(int i=1;i<maxn;i++){
		fro[i]=fro[i-1]*i%mod;
	}
	ni[maxn-1]=qpow(fro[maxn-1],mod-2);
	for(int i=maxn-1;i>0;i--){
		ni[i-1]=ni[i]*i%mod;
	}
}

void brc(ll *a,int l){
	for(int i=1,j=l/2;i<l-1;i++){
		if(i<j) swap(a[i],a[j]);
		int k=l/2;
		while(j>=k){
			j-=k;
			k>>=1;
		}
		if(j<k) j+=k;
	}
}

void ntt(ll *y,int l,int on){
	brc(y,l);
	int id=0;
	ll u,t,tmp;
	for(int h=2;h<=l;h<<=1){
		id++;
		for(int j=0;j<l;j+=h){
			ll w=1;
			for(int k=j;k<j+h/2;k++){
				u=y[k];
				t=w*y[k+h/2]%mod;
				y[k]=u+t;
				if(y[k]>=mod) y[k]-=mod;
				y[tmp=k+h/2]=u-t;
				if(y[tmp]<0) y[tmp]+=mod;
				w=w*qp[id]%mod;
			}
		}
	}
	if(on<0){
		for(int i=1;i<l/2;i++)
			swap(y[i],y[l-i]);
		ll ni=qpow(l,mod-2);
		for(int i=0;i<l;i++){
			y[i]=(y[i]*ni)%mod;
		}
	}
}

inline void debug(){
	cout<<"yes"<<endl;
}

int main(int argc, char const *argv[])
{
	init();
	int n,m;
	while(~scanf("%d",&n)){
		for(int i=0;i<=n;i++){
			scanf("%lld",K+i);
		}
		scanf("%d",&m);
		ll a=0;
		int x;
		for(int i=0;i<m;i++){
			scanf("%d",&x);
			a-=x;
			if(a<0) a=(a+mod)%mod;
		}
		int len=getlen(n+1);
		if(a==0){
			for(int i=0;i<=n;i++){
				printf("%lld",K[i]);
			}
			printf("\n");
			continue;
		}
		for(int i=0,aa=1;i<len;i++){
			if(i<=n){
				F1[i]=aa*ni[i]%mod;
				F2[i]=fro[n-i]*K[n-i]%mod;
			}
			else{
				F1[i]=F2[i]=0;
			}
			aa=1LL*aa*a%mod;
		}
		ntt(F1,len,1);
		ntt(F2,len,1);
		for(int i=0;i<len;i++){
			F1[i]=F1[i]*F2[i]%mod;
		}
		ntt(F1,len,-1);
		for(int i=0;i<=n;i++){
			ans[i]=F1[i];
			ans[i]=(ans[i]%mod+mod)*ni[n-i]%mod;
		}
		for(int i=0;i<=n;i++){
			printf("%lld ",ans[n-i]);
		}
		printf("\n");
	}
	return 0;
}