设FR(x)=xnF(x1), 可以发现FR(x)和F(x)的系数正好从大到小正好相反。
那么就有: F(x1)=Q(x1)G(x1)+R(x1)FR(x)=QR(x)GR(x)+xn−m+1RR(x)FR(x)≡QR(x)GR(x)(modxn−m+1)QR(x)≡GR(x)FR(x)(modxn−m+1)
然后就是一波求逆, 然后带入原式即可得到R(x)。
代码如下:
#include#include#include#include#include#include#define R register#define IN inline#define W while#define gc getchar()#define ll long long#define MOD 998244353#define g 3#define ginv 332748118#define MX 400500template<classT>
IN voidin(T &x){
x =0; R char c = gc;for(;!isdigit(c); c = gc);for(;isdigit(c); c = gc)
x =(x <<1)+(x <<3)+ c -48;}
IN intfpow(R int base, R int tim){int ret =1;
W (tim){if(tim &1) ret =1ll* ret * base % MOD;
base =1ll* base * base % MOD, tim >>=1;}return ret;}int n, m;int F[MX], G[MX], FR[MX], GR[MX], Q[MX], rev[MX], a[MX], b[MX], GRinv[MX], sur[MX];namespace Poly
{
IN voidNTT(int*dat, R int len, R int typ){for(R int i =1; i < len;++i)if(rev[i]> i) std::swap(dat[rev[i]], dat[i]);
R int seg, step, bd, now, cur, buf1, buf2, base, deal;for(seg =1; seg < len; seg <<=1){
base =fpow(typ ? g : ginv,(MOD -1)/(seg <<1)), step = seg <<1;for(now =0; now < len; now += step){
bd = now + seg, deal =1;for(cur = now; cur < bd;++cur, deal =1ll* deal * base % MOD){
buf1 = dat[cur], buf2 =1ll* dat[cur + seg]* deal % MOD;
dat[cur]=(buf1 + buf2)% MOD, dat[cur + seg]=(buf1 - buf2 + MOD)% MOD;}}}if(typ)return;int inv =fpow(len, MOD -2);for(R int i =0; i < len;++i) dat[i]=1ll* dat[i]* inv % MOD;}voidGetinv(R int up, R int lg,int*ans,int*ind){if(up ==1)return ans[0]=fpow(ind[0], MOD -2),void();Getinv(up >>1, lg -1, ans, ind); R int len = up <<1;for(R int i =1; i < len;++i) rev[i]=(rev[i >>1]>>1)|((i &1)<< lg -1);for(R int i =0; i < len;++i) a[i]= b[i]=0;for(R int i =0; i < up;++i) a[i]= ans[i], b[i]= ind[i];NTT(a, len,1),NTT(b, len,1);for(R int i =0; i < len;++i) a[i]=(2* a[i]% MOD -1ll* b[i]* a[i]% MOD * a[i]% MOD + MOD)% MOD;NTT(a, len,0);for(R int i =0; i < up;++i) ans[i]= a[i