萌新初学多项式,求助EXP
查看原帖
萌新初学多项式,求助EXP
108111
Lumos壹玖贰壹楼主2021/3/12 22:32

RT

谢谢大佬了,麻烦帮蒟蒻看看

求求了 听说exp很难调,果真

#include<bits/stdc++.h>
#define ll long long
#define ri register int
#define int long long
using namespace std;
const int maxn = 1 << 23,_G = 3,p = 998244353;
int r[maxn],G[maxn],A[maxn],B[maxn],a[maxn],b[maxn],c[maxn],df[maxn],n;
inline int rd(){
	int f = 0,res = 0;
	char ch = getchar();
	for(;!isdigit(ch);ch = getchar()) if(ch == '-') f = 1;
	for(;isdigit(ch);ch = getchar()) res = (res<<3) + (res<<1) + ch - 48;
	return f ? -res : res;
}
inline int qp(int x,int k){
	int res = 1;
	while(k){
		if(k & 1) res = 1ll * res * x % p;
		x = 1ll * x * x % p;
		k >>= 1;
	}
	return res;
}
inline void ntt(int *f,int lim,int type){
	for(ri i = 0;i < lim;++i) if(r[i] < i) swap(f[i],f[r[i]]);
	for(ri i = 1;i <= lim;i <<= 1){
		int gn = G[i];
		for(ri j = 0;j < lim;j += i){
			int gi = 1;
			for(ri k = j;k < j + (i >> 1);++k,gi = 1ll * gi * gn % p){
				int x = f[k],y = 1ll * f[k + (i >> 1)] * gi % p;
				f[k] = x + y;
				f[k + (i >> 1)] = (x + p - y) % p;
			}
		}
	}
	if(type == -1){
		reverse(f,f + lim);
		int inv = qp(lim,p - 2);
		for(ri i = 0;i < lim;++i) f[i] = 1ll * f[i] * inv % p;
	}
}
inline void Dao(int *f,int deg){
	for(ri i = 1;i < deg;++i) f[i - 1] = 1ll * f[i] * i % p;
	f[deg - 1] = 0;
}
inline void jifen(int *f,int deg){
	for(ri i = deg - 1;i >= 1;--i) f[i] = 1ll * f[i - 1] * qp(i,p - 2);
	f[0] = 0;
}
void getinv(int *f,int *g,int deg){
	if(deg == 1){
		g[0] = qp(f[0],p - 2);
		return;
	}
	getinv(f,g,(deg + 1)>>1);
	int lim = 1;
	while(lim < (deg<<1)) lim <<= 1;
	for(ri i = 1;i < lim;++i) r[i] = (r[i>>1] >> 1) | ((i & 1) ? (lim>>1) : 0);
	for(ri i = 0;i < deg;++i) a[i] = f[i]; for(ri i = deg;i < lim;++i) a[i] = 0;
	ntt(g,lim,1); ntt(a,lim,1);
	for(ri i = 0;i < lim;++i) g[i] = 1ll * g[i] * (2 - 1ll * a[i] * g[i] % p + p) % p;
	ntt(g,lim,-1); for(ri i = deg;i < lim;++i) g[i] = 0;
	return;
}
void getln(int *f,int *g,int deg){
	for(ri i = 0;i < deg;++i) df[i] = f[i];
	Dao(df,deg); getinv(f,g,deg);
	int lim = 1;
	while(lim < (deg<<1)) lim <<= 1;
	for(ri i = 1;i < lim;++i) r[i] = (r[i>>1]>>1) | ((i & 1) ? (lim>>1) : 0);

	for(ri i = deg;i < lim;++i) df[i] = 0;

	ntt(df,lim,1); ntt(g,lim,1);
	for(ri i = 1;i < lim;++i) g[i] = 1ll * df[i] * g[i] % p;
	ntt(g,lim,-1);
	jifen(g,deg); for(ri i = deg;i < lim;++i) g[i] = 0;
}
void exp(int *f,int *g,int deg){
	if(deg == 1){
		g[0] = 1;
		return;
	}
	exp(f,g,(deg+1)>>1);
	int lim = 1;
	while(lim < (deg<<1)) lim <<= 1;
	getln(g,c,deg);
	for(ri i = 0;i < lim;++i) r[i] = (r[i>>1] >> 1) | ((i&1) ? (lim >> 1) : 0);
	for(ri i = 0;i < deg;++i) b[i] = f[i]; for(ri i = deg;i < lim;++i) b[i] = 0;
	ntt(b,lim,1); ntt(g,lim,1); ntt(c,lim,1);
	for(ri i = 0;i < lim;++i) g[i] = 1ll * (1 + b[i] - c[i] + p) * g[i] % p;
	ntt(g,lim,-1); for(ri i = deg;i < lim;++i) g[i] = 0;
}
signed main(){
	n = rd();
	for(ri i = 2;i < maxn;i <<= 1) G[i] = qp(_G,(p-1)/i);
	for(ri i = 0;i < n;++i) A[i] = rd();
	exp(A,B,n);
	for(ri i = 0;i < n;++i) printf("%lld ",B[i]); puts("");
	return 0;
}
2021/3/12 22:32
加载中...