這是多項式的大頭了,實際使用多項式的和,這裏呢,也只講和的做法。
1.多項式快速冪
P5245 【模板】多項式快速冪
P5273 【模板】多項式冪函數 (加強版)
已知:
顯然求和就可以出答案了。
既然要求和,那麼一定要考慮的是常數項的問題,洛谷的常規題面有保證 ,所以說無腦套模板就對了。
那麼加強版沒有保證 ,我們如何算常數項呢?
容易知道,的常數項爲 ,的常數項是。好像算不出來呢。
可是,所以說的常數項是就應該是的常數項,既 。
所以說我們直接知道的常數項了,就不管他的常數項啦。
注意當時,常數項也應該是,可是……常數項真的可以爲嗎?
我們是要求 的,分母當然不能爲 了,所以說我們還是要單獨處理 的情況的。
把爲的前綴提出來,然後算,最後在答案前面加上提出的長度乘上個即可,模板沒有管這個,需要自己注意。
inline Polynomial Power(const Polynomial &a,const int &K){
int size=a.size();
Polynomial p_a=Logarithmic(a);
p_a.resize(size);
for(register int i=1;i<size;++i)p_a[i]=1ll*p_a[i]*K%mod;
return Exponential(p_a,power(a[0],K%(mod-1)));
//這裏求a[0]^k,用了歐拉定理優化
}
2.多項式開方
P5205 【模板】多項式開根
P5277 【模板】多項式開根 (加強版)
已知:
同理,求後,常數項帶入 求 就可以出答案了,不是加強版的照樣直接貼模板也可以。
那麼求常數項就比較講究了,我們要求的是,也就是 在 意義下的二次剩餘。
如果會二次剩餘,可以求,不行還可以花時間 求,時間差別不大,就先不放代碼了,代碼放在下一個環節,同理常數項爲 的時候要特殊判斷。
3.多項式開高次方
已知:
同理,求後,常數項帶入 求 就可以出答案了,現在主要是說一下如何用 求 ,高次剩餘。
因爲需要保證有逆元或者可以直接除,所以需要保證 ,或者 與 互質。
inline int BSGS(int a,int b){
unordered_map<int,int>hash;hash.clear();b%=mod;
int t=(int)sqrt(mod)+1;
for(register int j=0;j<t;j++)hash[(int)(1ll*b*power(a,j)%mod)]=j;
a=power(a,t);
if(a==0)return b?-1:1;
for(register int i=0,val;i<=t;++i){
int j=hash.find(val=power(a,i))==hash.end()?-1:hash[val];
if(j>=0)return i*t-j;
}
return -1;
}
inline int Kth_Remaining(int a,int K){
int P=BSGS(mod_g,a);
if(P%K==0)P/=K;
else{int x,y;exgcd(K,mod-1,x,y);if(x<0)x+=(mod-1);P=1ll*P*x%(mod-1);}
int ret=power(mod_g,P);
if(!(K&1))ret=min(ret,mod-ret);
return ret;
}
inline Polynomial Kth_root(const Polynomial &a,const int &K){
int size=a.size();
Polynomial s_a=Logarithmic(a);
s_a.resize(size);
int Kr=Inv(K);
for(register int i=1;i<size;++i)s_a[i]=1ll*s_a[i]*Kr%mod;
return Exponential(s_a,Kth_Remaining(a[0],K));
}