多項式全家桶(零):前置和目錄

       \ \ \ \ \ \ \,終於把多項式差不多弄完了,可以找個機會在退役前把多項式整理封裝弄好,也算是留下了一點東西吧(嘿嘿。

       \ \ \ \ \ \ \,這一部分實例的代碼是用 std::vectorstd::vector 封裝好的,這篇博客先提一下前置:


       \ \ \ \ \ \ \,首先是可能需要用到的定義,都是比較基礎的數論知識,不贅述了:

#define Polynomial vector<int>
//封裝多項式爲 std::vector,方便resize等操作
void print(Polynomial &a,int len){for(int i=0;i<len;i++)printf("%d ",a[i]);}
const int mod=998244353,mod_g=3,img=86583718;
//mod爲多項式係數的取模值,mod_g是它的原根,img爲在模意義下的虛部,只有多項式三角函數會遇到。
int gcd(int a,int b){return b?gcd(b,a%b):a;}
void exgcd(int a,int b,int &x,int &y){
	if(!b){x=1;y=0;return;}
	exgcd(b,a%b,y,x);y-=x*(a/b);
}
//gcd,exgcd只有在開根的時候會用到
int power(int a,int b)
{int ans=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;}
#define Inv(x) power(x,mod-2)

      &ThinSpace;\ \ \ \ \ \ \,然後是核心的快速數論變換 NTTNTT,相關請看【求多項式卷積的變換】

Polynomial R;
inline int Binary_Rounding(const int &n)
{int len=1;for(;len<n;len<<=1);return len;}
//二進制向上取整,爲方便NTT變換準備。
inline int Prepare_Transformation(int n){
  	int L=0,len;for(len=1;len<n;len<<=1)L++;R.clear();R.resize(len);
  	for(int i=0;i<len;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
  	return len;
}
//預處理R數組,準備變換,在每次NTT之前理論都要調用此函數。
void NTT(Polynomial &a,int f){
	int n=a.size();
	for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
  	for(int i=1;i<n;i<<=1)
  	for(int j=0,gn=power(mod_g,(mod-1)/(i<<1));j<n;j+=(i<<1))
  	for(int k=0,g=1,x,y;k<i;k++,g=1ll*g*gn%mod)
	  	x=a[j+k],y=1ll*g*a[i+j+k]%mod,
	  	a[j+k]=(x+y)%mod,a[i+j+k]=(x-y+mod)%mod;
  	if(f==-1){
   		reverse(a.begin()+1,a.end());
    	int inv=Inv(n);
    	for(int i=0;i<n;i++)a[i]=1ll*a[i]*inv%mod;
  	}
}

      &ThinSpace;\ \ \ \ \ \ \,在掌握上面簡單知識後,就可以進行多項式的入門了,我差不多按照學習的拓撲序給出下面的目錄,也分開記錄一下自己的模板:

      &ThinSpace;\ \ \ \ \ \ \,對了,還是建議用 vectorvector 的,用數組的話,到時候對於臨時數組的清空問題會讓你懷疑人生的!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章