一般質問の意味:与えられた多項式\(F.(X)\) 、求めている\(G(x)が\)を満たす\(F.(X)* G(X)\ equiv1(MOD \ X ^ N-)\) 、\(998244353 \)を法。
序文
ボードの問題が唯一の問題への解決策をコピーします......
私はハードはこのアイデアを考えていますが、言っているが、問題への解決策を見ているか十分に理解します。
プッシュ式
私たちは、この問題を解決するために再帰的にすることができます。
境界、明らか場合再帰\(N = 0 \)を得ることができ、直接\(G(x)\)で\(0 \)係数用語ビュー(すなわち、定数項)である\(F(X )\)中)(\ 0 \次項係数逆。
そうでなければ、それは我々が現在知られていることを前提としています。
\ [F(X)* H(X)\ equiv1(MOD \ X ^ {\ lfloor \ FRAC N2 \ rfloor})\]
ための\(F(X)* G ^ N-X(X)\ equiv1(MOD \)\) 、それは明らかです
\ [F(X)* G(X)\ equiv1(MOD \ X ^ {\ lfloor \ FRAC N2 \ rfloor})\]
我々は二つの式を引く場合次に、あなたが得ることができます:
\ [F(X)*(G(x)-H(X))\ equiv0(MOD \ X ^ {\ lfloor \ FRAC N2 \ rfloor})\]
\(F(x)は\)を取得、削除:
\ [G(X)-H(X)\ equiv0(MOD \ X ^ {\ lfloor \ FRAC N2 \ rfloor})\]
私たちは今、多項式、会うの要件を考慮し\(F(X)を\)畳み込みモジュール(\ n個のx ^)\ I \(1 \) 。
私達がで弾性率が、ここで聞かせて、道を見つけなければならないことは明らかである\(X ^ {\ lfloor \ FRAC N2 \ rfloor} \) となり\(N-X- ^ \) 。
どのようにそれを行うには?同時に方程式の両側に四角い缶。すなわち:
\ [(G(x)-H(X))^ 2 \ equiv0(MOD \ X ^ N)\]
完全な方形式の正方形の解体:
\ [G(X)^ 2-2G(X)* H(X)+ H(X)^ 2 \ equiv0(MOD \ X ^ N)\]
そして、我々その後、\(F(x)は\)畳み込みアップ、我々が得ます:
\ [F(X)* G(X)^ 2-2F(X)* G(X)* H(X)+ F(X)* H(X)^ 2 \ equiv0(MOD \ X ^ N)\ ]
以来(F(X-)* G(X-)\ equiv1(MOD \ N-X- ^)\)\、我々はさらに簡略化され得ることができるように:
\ [G(X)-2H-(X)+ F(X)* H(X)^ 2 \ equiv0(MOD \ X ^ N)\]
この時点では、式を見つけることができます\(G(X)を\)あなたはシフトキーを介して取得することができている限り、独立していました:
\ [G(X)\ equiv2H(X)-F(X)* H(X)^ 2(MOD \ X ^ N)\]
この式では、限り(NTT \)\それに多項式の乗算を行います。
注特定の実装において、その\(G(X)\)と\(H(X)\)提示することができるアレイ。
コード
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 998244353
#define Qinv(x) Qpow(x,X-2)
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int n,a[N+5],b[4*N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void write(Con Ty& x,Con char& y) {write(x),pc(y);}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
template<int SZ,int PR> class Poly
{
private:
int IPR,P,L,R[4*N+5],t[4*N+5];
I void T(int *s,CI op)
{
RI i,j,k,U,S,x,y;for(i=0;i^P;++i) i<R[i]&&swap(s[i],s[R[i]]);
for(i=1;i^P;i<<=1) for(U=Qpow(~op?PR:IPR,(X-1)/(i<<1)),j=0;j^P;j+=i<<1)
for(S=1,k=0;k^i;++k,S=1LL*S*U%X) s[j+k]=((x=s[j+k])+(y=1LL*S*s[i+j+k]%X))%X,s[i+j+k]=(x-y+X)%X;
}
public:
I Poly() {IPR=Qinv(PR);}
I void Inv(CI n,int *a,int *b)
{
if(!n) return (void)(b[0]=Qinv(a[0]));Inv(n>>1,a,b);//处理边界,不在边界则继续递归
RI i;P=1,L=0;W(P<=(n<<1)) P<<=1,++L;for(i=0;i^P;++i) R[i]=(R[i>>1]>>1)|((i&1)<<L-1);//预处理
for(i=0;i<=n;++i) t[i]=a[i];T(b,1),T(t,1);//NTT
for(i=0;i^P;++i) b[i]=(2LL*b[i]%X-1LL*t[i]*b[i]%X*b[i]%X+X)%X;T(b,-1);//计算新多项式
RI t=Qinv(P);for(i=0;i<=n;++i) b[i]=1LL*b[i]*t%X;for(i=n+1;i^P;++i) b[i]=0;//注意将高位清空,否则会影响后续操作
}
};Poly<N,3> P;
int main()
{
RI i;for(F.read(n),--n,i=0;i<=n;++i) F.read(a[i]);//读入
for(P.Inv(n,a,b),i=0;i<=n;++i) F.write(b[i]," \n"[i==n]);return F.clear(),0;//输出
}