天天看點

多項式全家桶(一):多項式的加,減,卷積

         \ \ \ \ \ \ \,       多項式的加,減,卷積,是比較基本的多項式操作,以模拟和 N T T NTT NTT 為主,主要是展示和記錄模闆的操作。

         \ \ \ \ \ \ \,        單項式其實就是常數。

1. 多項式加,減單項式

inline Polynomial operator +(const Polynomial &a,const int &b){
	int sizea=a.size();Polynomial ret=a;ret.resize(sizea);
	for(int i=0;i<sizea;i++)ret[i]=(1ll*a[i]+b+mod)%mod;
	return ret;
}
inline Polynomial operator -(const Polynomial &a,const int &b){
	int sizea=a.size();Polynomial ret=a;ret.resize(sizea);
	for(int i=0;i<sizea;i++)ret[i]=(1ll*a[i]-b+mod)%mod;
	return ret;
}
           

2. 多項式卷積單項式

inline Polynomial operator *(const Polynomial &a,const int &b){
	int sizea=a.size();Polynomial ret=a;ret.resize(sizea);
	for(int i=0;i<sizea;i++)ret[i]=(1ll*a[i]*b%mod+mod)%mod;
	return ret;
}
           

3. 多項式加,減多項式

       &ThinSpace; \ \ \ \ \ \ \,       注意 v e c t o r vector vector 在指派之前,一定先要 r e s i z e resize resize 到合适的位置,不然就會一直 R E RE RE 了。

inline Polynomial operator +(const Polynomial &a,const Polynomial &b){
	int sizea=a.size(),sizeb=b.size(),size=max(sizea,sizeb);
	Polynomial ret=a;ret.resize(size);
	for(int i=0;i<sizeb;i++)ret[i]=(1ll*ret[i]+b[i])%mod;
	return ret;
}
inline Polynomial operator -(const Polynomial &a,const Polynomial &b){
	int sizea=a.size(),sizeb=b.size(),size=max(sizea,sizeb);
	Polynomial ret=a;ret.resize(size);
	for(int i=0;i<sizeb;i++)ret[i]=(1ll*ret[i]-b[i]+mod)%mod;
	return ret;
}
           

4. 多項式卷積多項式

       &ThinSpace; \ \ \ \ \ \ \,       P3803 【模闆】多項式乘法(FFT)(可以NTT過

inline Polynomial operator *(const Polynomial &a,const Polynomial &b){
	Polynomial lsa=a,lsb=b,ret;
	int n=lsa.size(),m=lsb.size();
	n=Prepare_Transformation(n+m);
  	lsa.resize(n);lsb.resize(n);ret.resize(n);
  	NTT(lsa,1);NTT(lsb,1);
  	for(int i=0;i<n;i++)ret[i]=1ll*lsa[i]*lsb[i]%mod;
  	NTT(ret,-1);return ret;
}
           

5. 多項式除法和取模

       &ThinSpace; \ \ \ \ \ \ \,       你問我多項式除法(P4512 【模闆】多項式除法)???多項式除法滾出多項式全家桶!!!(超兇

       &ThinSpace; \ \ \ \ \ \ \,       看了下一篇 求逆 過後,應該可以自己完成多項式除法了,但是在很多小地方……容易自閉。

       &ThinSpace; \ \ \ \ \ \ \,       還是貼一下闆子吧,小心别一開始二進制取整了:

inline Polynomial operator /(const Polynomial &a,const Polynomial &b){
	Polynomial ret=a,ls=b;
  	reverse(ret.begin(),ret.end());
  	reverse(ls.begin(),ls.end());
	ls.resize(Binary_Rounding(a.size()+b.size()));
	ls=Inverse(ls);
	ls.resize(a.size()+b.size());
	ret=ret*ls;ret.resize(a.size()-b.size()+1);
  	reverse(ret.begin(),ret.end());
	return ret;
}
inline Polynomial operator %(const Polynomial &a,const Polynomial &b){
	Polynomial ret=a/b;
	ret=ret*b;ret.resize(a.size()+b.size());
	ret=a-ret;ret.resize(a.size()+b.size());
	return ret;
}