apple365 的多项式合集!

重振卡门雄风,吾辈义不容辞!

目录:

  1. 快速傅里叶变换(FFT)
  2. NTT

正文

一,快速傅里叶变换(FFT)

前置芝士:

概念

  • 时域:以时间为自变量,函数值为因变量的平面。
  • 频域:以频率为自变量,振幅为因变量的坐标系。
  • 多项式的系数表示法:\(A(x)=\sum_{k=0}^{n-1} a_k\times x^k\)
  • 多项式的点值表示法:用 \(n\) 个点描述一个 \(n-1\) 次的多项式。

复数

复数=实部+虚部
\(x=a+ib(i^2=-1)\)
对应的会有一个“复平面”。
\((a+ib)\times(c+id)=(ac-bd)+i(ad+bc)\)
\(n\) 次单位复数根:\(\omega^n=1\)\(\omega\) 是复数。
用三角函数理解:\(e^{ix}=\cos(x)+i\times\sin(x)\)
定义 \(\omega_n=e^{\frac{2\pi i}{n}}\)\(n\) 次单位根。
\(\omega_n^k=e^{\frac{2\pi ik}{n}}\)
引理:

  1. 消去引理:当 \(n\ge0,k\ge0,d\ge0\)\(\omega_{dk}^{dk}=\omega_n^k\)\((e^{\frac{2\pi i}{dn}})^{dk}=(e^{\frac{2\pi i}{n}})^k\)
  2. 折半引理:若 \(n>0\)\(n\%2=0\),则 \(n\)\(n\) 次单位复数根的平方的集合就是 \(\frac{n}{2}\)\(\frac{n}{2}\) 次复数根的集合。也就是说,\((\omega_n^k)^2=\omega _\frac{n}{2}^k\)
  3. 求和引理:\(\sum_{j=0}^{n-1}(\omega_n^k)^j=0\),其中 \(n\ge1\)\(k\) 不整除 \(n\)\(k\ge0\)
    对于 \(j,k=0,1,2,...,n-1\)\(V_n^{-1}(V 是系数矩阵)\)\((j,k)\) 的值是 \(\frac{\omega_n^{-kj}}{n}\)
    \(a_j=\frac{1}{n}\sum_{k=0}^{n-1}y_k\omega_n^{-kj}\)

定义 \(y_k=A(\omega_n^k)=\sum_{i=0}^{n-1} a_i\times\omega_n^{ki}\)
假设 \(n\) 是偶数。
\(A(x)=a_0+a_1x+a_2x^2+...+a_{n-1}x^{n-1}\)
\(A_0(x)=a_0+a_2x^2+a_4x^4+...+a_{n-2}x^{n-2}\)
\(A_1(x)=a_1x+a_3x^3+a_5x^5+...+a_{n-1}x^{n-1}\)
\(A(x)=A_0(x^2)+A_1(x^2)\times x\)

欧拉公式

\(e^{i\pi}=-1\)
拓展:\(e^{ix}=\cos x+i\times\sin x\)

流程:

\(A(x) (a_0,a_1,...,a_{n-1}),B(x) (b_0,b_1,...,b_{n-1})\)
通过 FFT
\(A(x_0)\times B(x_0),A(x_1)\times B(x_1)...A(x_{2n-2})\times B(x_{2n-2})\)
通过点值乘法
\(C(x_0),...,C(x_{2n-1})\)
通过 FFT 插值
\(C(x)={C_0,C_1,...,C_{2n-2}}\)

标程

查看代码
#include<bits/stdc++.h>
//#define int long long
#define db double
using namespace std;
struct comp{
	db a,b;
	comp(){
	}
	comp(db _a,db _b){
		a=_a,b=_b;
	}
	friend comp operator *(comp x,comp y){
		return comp(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);
	}
	friend comp operator +(comp x,comp y){
		return comp(x.a+y.a,x.b+y.b);
	}
	friend comp operator -(comp x,comp y){
		return comp(x.a-y.a,x.b-y.b);
	}
};
const int N=1000005;
comp I=comp(0.0,1.0);
const db pi=acos(-1.0);
int n,m;
comp a[N*3],b[N*3],tmp[N*3],ans[N*3];
void fft(comp* a,int len,int opt=1){
	if(len==1)return;
	comp* a0=new comp[len/2];
	comp* a1=new comp[len/2];
	for(int i=0;i<len;i+=2){
		a0[i/2]=a[i];
		a1[i/2]=a[i+1];
	}
	fft(a0,len>>1,opt);
	fft(a1,len>>1,opt);
	comp w_n=comp(cos(2*pi/len),opt*sin(2*pi/len));
	comp w=comp(1,0);
	for(int i=0;i<(len/2);++i){
        a[i]=a0[i]+w*a1[i];
        a[i+len/2]=a0[i]-w*a1[i];
        w=w*w_n;
    }
    delete[]a0;
    delete[]a1;
    return;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=0;i<=n;++i)cin>>a[i].a;
	for(int i=0;i<=m;++i)cin>>b[i].a;
	int lim=1;
	while(lim<=n+m)lim<<=1;
	fft(a,lim);
	fft(b,lim);
	for(int i=0;i<=lim;++i)a[i]=a[i]*b[i];
	fft(a,lim,-1);
	for(int i=0;i<=n+m;++i)cout<<(int)(a[i].a/lim+0.5)<<' ';
	return 0; 
}

二.NTT

用原根代替一波单位根。

std:(分治 ver)

查看代码
#include<bits/stdc++.h>
#define int long long
#define swap(a,b) {auto c=a;a=b;b=c;}
using namespace std;
int rev[4000005];
const int N=1e6+5,mod=998244353,g=3,gi=332748118;
int n,m;
int qpow(int a,int b){
	int ans=1,base=a;
	while(b){
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1; 
	}
	return ans;
}
int a[N*3],b[N*3],c[N*3];
void NTT(int* A,int n,int flag=1){
	for(int i=0;i<n;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
	for(int mid=1;mid<n;mid<<=1) {
		int wn=qpow(flag==1?g:gi,(mod-1)/(mid<<1));
		for(int i=0;i<n;i+=(mid<<1)) {
			int w=1;
			for(int j=0;j<mid;++j,w=(w*wn)%mod){
				int tmp0=A[i+j],tmp1=w*A[i+mid+j]%mod;
				A[i+j]=(tmp0+tmp1)%mod;
				A[i+mid+j]=(tmp0-tmp1)%mod;
			}
		}
	}
    return;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=0;i<=n;++i){
		cin>>a[i];
		a[i]=(a[i]%mod+mod)%mod;
	}
	for(int i=0;i<=m;++i)cin>>b[i];
	int lim=1,L=0;
	while(lim<=n+m)lim<<=1,++L;
	for(int i=0;i<=lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
	NTT(a,lim,1),NTT(b,lim,1);
	for(int i=0;i<=lim;++i)a[i]=a[i]*b[i]%mod;
	NTT(a,lim,-1);
	for(int i=0;i<=n+m;++i)cout<<(a[i]*qpow(lim,mod-2)%mod+mod)%mod<<' ';
	return 0;	
}	
posted @ 2023-04-09 21:06  Forever1507  阅读(27)  评论(0编辑  收藏  举报