FFT/NTT板子

FFT

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const double Pi = acos(-1.0);
int n,m,rev[2100005];

struct complex{
	double x,y;
	inline complex operator + (const complex &a) const{return complex{x + a.x,y + a.y};}
	inline complex operator - (const complex &a) const{return complex{x - a.x,y - a.y};}
	inline complex operator * (const complex &a) const{return complex{x * a.x - y * a.y,x * a.y + y * a.x};}
}a[2100005],b[2100005];
void FFT(complex *a,int lent,int inv)
{
	if (lent == 1) return;
	for (int i = 0; i < lent; ++i)
		if (i < rev[i]) swap(a[i],a[rev[i]]);
	for (int l = 1; l < lent; l <<= 1)
	{
		complex I = complex{cos(Pi / l),inv * sin(Pi / l)};
		for (int i = 0; i < lent; i += (l << 1))
		{
			complex w = complex{1,0};
			for (int j = 0; j < l; ++j,w = w * I)
			{
				complex x = a[i + j],y = w * a[i + j + l];
				a[i + j] = x + y,a[i + j + l] = x - y;
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i = 0; i <= n; ++i) scanf("%lf",&a[i].x);
	for (int i = 0; i <= m; ++i) scanf("%lf",&b[i].x);
	int len = 1,bit = 0;
	while (len <= n + m) len <<= 1,++bit;
	for (int i = 0; i < len; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
	FFT(a,len,1),FFT(b,len,1);
	for (int i = 0; i < len; ++i) a[i] = a[i] * b[i];
	FFT(a,len,-1);
	for (int i = 0; i <= n + m; ++i) printf("%d ",(int)(a[i].x / len + 0.5));
}

NTT

#include<cstdio>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int P = 998244353;
int n, m, rev[2100005];
LL a[2100005], b[2100005];

inline int read()
{
	int res = 0;
	char ch = getchar();
	for (; !isdigit(ch); ch = getchar()) ;
	for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ 48);
	return res;
}
LL ksm(LL x,LL y)
{
	LL res = 1;
	while (x)
	{
		if (x & 1) res = res * y % P;
		y = y * y % P;
		x >>= 1;
	}
	return res;
}
void NTT(LL *a,int limit,int fl)
{
	if (limit == 1) return;
	for (int i = 0; i < limit; i++)
		if (i < rev[i]) swap(a[i],a[rev[i]]);
	for (int l = 1; l < limit; l <<= 1)
	{
		LL I = ksm((P - 1) / (l << 1),3);
		if (fl == -1) I = ksm(P - 2,I);
		for (int i = 0; i < limit; i += (l << 1))
		{
			LL W = 1;
			for (int j = 0; j < l; j++,W = W * I % P)
			{
				LL x = a[i + j] % P,y = W * a[i + j + l] % P;
				a[i + j] = (x + y) % P,a[i + j + l] = (x - y + P) % P;
			}
		}
				
	}
}
int main()
{
	n = read(),m = read();
	for (int i = 0; i <= n; i++) a[i] = read();
	for (int i = 0; i <= m; i++) b[i] = read();
	int len = 1,bit = 0;
	while (len <= n + m) len <<= 1,bit++;
	for (int i = 0; i < len; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
	NTT(a,len,1),NTT(b,len,1);
	for (int i = 0; i < len; i++) a[i] = a[i] * b[i] % P;
	NTT(a,len,-1);
	LL inv = ksm(P - 2,len);
	for (int i = 0; i <= n + m; i++) printf("%lld ",a[i] * inv % P);
}
posted @ 2021-08-21 16:43  RiverSheep  阅读(59)  评论(0编辑  收藏  举报