一些多项式的整理

卷积

\(c=a \otimes b\)

\(c_i=\sum_{j=0}^{i} a_j b_{i-j}\)

卷积运算的性质也就是多项式乘法的性质:

交换律:\(a \otimes b=b \otimes a\)

结合律:\((a \otimes b) \otimes c=a \otimes (b \otimes c)\)

分配律:\((a+b) \otimes c=a \otimes c+b \otimes c\)

FFT

用于优化两个多项式的卷积,时间复杂度\(O(nlogn)\)

struct node{
    double x,y;
    inline node operator + (const node &b)const{return (node){x+b.x,y+b.y};}
    inline node operator - (const node &b)const{return (node){x-b.x,y-b.y};}
    inline node operator * (const node &b)const{return (node){x*b.x-y*b.y,y*b.x+x*b.y};}
}a[N],b[N];
int pos[N];
inline void init(){
    for (n=1;n<=na+nb;n<<=1,l++);
    For(i,1,n) pos[i]=(pos[i>>1]>>1)|((i&1)<<(l-1));
}
inline void FFT(node *a,int f){
    For(i,0,n-1) if (i<pos[i]) swap(a[i],a[pos[i]]);
    node x,y;
    for (register int i=1;i<n;i<<=1){
    	node wn=(node){cos(pi/i),f*sin(pi/i)};
        for (register int j=0;j<n;j+=i<<1){
        	node w=(node){1,0};
            for (register int k=0;k<i;k++,w=w*wn) x=a[j+k],y=a[j+i+k]*w,a[j+k]=x+y,a[j+i+k]=x-y;
        }
    }
    if (f==-1) For(i,0,n-1) a[i].x=a[i].x/n+0.5;
}

NTT

用来处理有特定模数(如\(998244353\))的卷积,把\(FFT\)的单位复根换成原根。
模数表

const int mod = 998244353;
inline int power(int a,int b){
	int ret=1;
	for (;b;b>>=1,a=1ll*a*a%mod) if (b&1) ret=1ll*ret*a%mod;
	return ret;
}
inline int Mod(int x){return x=(x<0)?x+mod:x,x=(x>=mod)?x-mod:x,x;}
inline void NTT(int n,vector<int>&a,int f){
	a.resize(n);
	For(i,0,n-1) if (i<pos[i]) swap(a[i],a[pos[i]]);
	for (rt i=1;i<n;i<<=1){
        int wn=power(3,(mod-1)/2/i);
        for (rt j=0;j<n;j+=i<<1)
        	for (rt k=0,w=1;k<i;k++,w=1ll*w*wn%mod){
        		int x=a[j+k],y=1ll*w*a[j+k+i]%mod;
        		a[j+k]=Mod(x+y),a[j+k+i]=Mod(x-y);
        	}
	}
	if (f==-1){
		reverse(a.begin()+1,a.end());
		for (rt i=0,inv=power(n,mod-2);i<n;i++) a[i]=1ll*a[i]*inv%mod;
	}
}

倍增FFT

套个卡速米就行了。

inline vector<int> Power(vector<int>a,int b){
	vector<int> ret=a;b--;
	for (;b;b>>=1,a=Mul(a,a)) if (b&1) ret=Mul(ret,a);
	return ret;
}

分治FFT

\(f_i=\sum_{j=1}^{i}f_{i-j}g_j\)

套个\(CDQ\)就行了。

inline void Solve(int l,int r){
	if (l==r) return;
	int mid=l+r>>1;Solve(l,mid);
	vector<int>A,B,C;
	For(i,l,mid) A.push_back(f[i]);
	For(i,0,r-l) B.push_back(g[i]);
	C=Mul(A,B);
	For(i,mid+1,r) f[i]=Mod(f[i]+C[i-l]);
	Solve(mid+1,r);
}

多项式求逆

咕咕咕

多项式除法/取模

咕咕咕

多项式牛顿迭代法

咕咕咕

多项式开根

咕咕咕

多项式ln

咕咕咕

多项式exp

咕咕咕

咕咕咕的等会了再填坑...

posted @ 2019-01-05 19:41  zykykyk  阅读(219)  评论(5编辑  收藏