非常优雅的马蜂
#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i)
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define cp complex<double>
#define fir first
#define sec second
using namespace std;
const int maxn=4e6+10,Mod=998244353;
int pw(int x,int p){int res=1,base=x;while(p){if(p&1)res=1LL*res*base%Mod;base=1LL*base*base%Mod;p>>=1;}return res;}
int Inv(int x){return pw(x,Mod-2);}
int W[maxn],Cw[maxn],rev[maxn];
int deg,lg;
void Init(int len){
deg=1,lg=0;while(deg<len)deg<<=1,++lg;
W[0]=Cw[0]=1;int Wp=pw(3,(Mod-1)/deg),Cp=pw(Inv(3),(Mod-1)/deg);
for(int i=1;i<deg;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)),W[i]=1LL*W[i-1]*Wp%Mod,Cw[i]=1LL*Cw[i-1]*Cp%Mod;
}
struct Poly{
vector<int>f;
int &operator[](const int &i){return f[i];}
int operator[](const int &i)const{return f[i];}
int Deg(){return f.size();}
int Deg()const{return f.size();}
void Set(int len){f.resize(len);}
void Adjust(){while(f.size()>1 && f.back()==0)f.pop_back();}
void Reverse(){reverse(f.begin(),f.end());}
void Print(){for(auto it : f)cerr<<it<<" ";cerr<<"\n";}
void Diri(){for(int i=0;i+1<(int)f.size();++i)f[i]=1LL*f[i+1]*(i+1)%Mod;f.back()=0;}
void Integ(){for(int i=((int)f.size())-1;i>=1;--i)f[i]=1LL*f[i-1]*::Inv(i)%Mod;f[0]=0;}
Poly Dir(){Poly res;res.Set(Deg());for(int i=0;i+1<f.size();++i)res[i]=1LL*f[i+1]*(i+1)%Mod;return res;}
Poly Inte(){Poly res;res.Set(Deg());for(int i=((int)f.size()-1);i>=1;--i)res[i]=1LL*f[i-1]*::Inv(i)%Mod;return res;}
void NTT(int deg,int w[],int opt){
Set(deg);for(int i=0;i<deg;++i)if(i<rev[i])swap(f[i],f[rev[i]]);
for(int t=deg>>1,m=1;m<deg;m<<=1,t>>=1)for(int i=0;i<deg;i+=(m<<1))for(int j=0;j<m;++j)
{ int x=f[i+j],y=1LL*w[t*j]*f[i+j+m]%Mod;f[i+j]=(x+y)%Mod,f[i+j+m]=(x-y+Mod)%Mod;}
if(opt==-1){int inv=::Inv(deg);for(int i=0;i<deg;++i)f[i]=1LL*f[i]*inv%Mod;}
}
friend Poly operator + (const Poly &x,const Poly &y){
Poly res; res.Set(max(x.Deg(),y.Deg()));
for(int i=0;i<x.Deg();++i)res[i]=x[i];
for(int i=0;i<y.Deg();++i)res[i]=(res[i]+y[i])%Mod;
return res;
}
void operator += (const Poly &x){
Set(max(Deg(),x.Deg()));
for(int i=0;i<x.Deg();++i)f[i]=(f[i]+x[i])%Mod;
}
friend Poly operator - (const Poly &x,const Poly &y){
Poly res; res.Set(max(x.Deg(),y.Deg()));
for(int i=0;i<x.Deg();++i)res[i]=x[i];
for(int i=0;i<y.Deg();++i)res[i]=(res[i]-y[i]+Mod)%Mod;
return res;
}
void operator -= (const Poly &x){
Set(max(Deg(),x.Deg()));
for(int i=0;i<x.Deg();++i)f[i]=(f[i]-x[i]+Mod)%Mod;
}
friend Poly operator * (const Poly &x,const Poly &y){
Poly res,A=x,B=y;
Init(A.Deg()+B.Deg()-1);
A.NTT(deg,W,1);B.NTT(deg,W,1);res.Set(deg);
for(int i=0;i<deg;++i)res[i]=1LL*A[i]*B[i]%Mod;
res.NTT(deg,Cw,-1);res.Adjust();
return res;
}
void operator *= (const Poly &x){
Poly A=x;
Init(Deg()+A.Deg()-1);
NTT(deg,W,1),A.NTT(deg,W,1);
for(int i=0;i<deg;++i)f[i]=1LL*f[i]*A[i]%Mod;
NTT(deg,Cw,-1);Adjust();
}
friend Poly operator / (const Poly &x,const Poly &y){
Poly E=x,D=y;
E.Reverse(),D.Reverse();D.Set(x.Deg()-y.Deg()+1);
D=D.Inv();D*=E;
D.Set(x.Deg()-y.Deg()+1); D.Reverse();
return D;
}
friend pair<Poly,Poly> operator % (const Poly &x,const Poly &y){
Poly E=x,D=y;
E.Reverse(),D.Reverse();D.Set(x.Deg()-y.Deg()+1);
D=D.Inv();D*=E;
D.Set(x.Deg()-y.Deg()+1); D.Reverse();
Poly R=x-D*y; R.Set(x.Deg()-1);
return {D,R};
}
Poly Inv(){
Poly res;res.Set(1);
if(f.empty())return res;
int len,lim;res[0]=::Inv(f[0]);Poly A,B;
for(len=2;len<(Deg()<<1);len<<=1){
A.f.assign((*this).f.begin(),(*this).f.begin()+min(len,Deg())),B=res;
B.Set(min(len,Deg()));
Init(A.Deg()+B.Deg()-1);A.NTT(deg,W,1),B.NTT(deg,W,1);res.Set(deg);
for(int i=0;i<deg;++i)res[i]=((2LL-1LL*A[i]*B[i]%Mod)*B[i]%Mod+Mod)%Mod;
res.NTT(deg,Cw,-1);
res.Set(len);
}
res.Set(Deg());return res;
}
Poly Ln(){
Poly res=Dir();Poly I=Inv();
res*=I;res.Integ(); res.Set(Deg());
return res;
}
Poly Exp(){
Poly res;res.Set(1);res[0]=1;
int len;Poly A,B;
for(len=2;len<(Deg()<<1);len<<=1){
res.Set(len);A=res.Ln();
B.f.assign((*this).f.begin(),(*this).f.begin()+min(len,Deg()));
B-=A;B[0]++;res*=B;
res.Set(len);
}
res.Set(Deg());return res;
}
Poly Pow(int k){
Poly res=Ln();
for(int i=0;i<res.Deg();++i)res[i]=1LL*res[i]*k%Mod;
return res.Exp();
}
Poly Sqrt(){
Poly res;res.Set(1);res[0]=1;
int len;Poly A,B;int inv2=::Inv(2);
for(len=2;len<(Deg()<<1);len<<=1){
res.Set(len);A=res.Inv();
B.f.assign((*this).f.begin(),(*this).f.begin()+min(len,Deg()));
A*=B;
for(int i=0;i<len;++i)res[i]=1LL*(res[i]+A[i])*inv2%Mod;
res.Set(len);
}
res.Set(Deg());return res;
}
}F,G;
int n,m;
void solve(){ }
int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }
标签:封装,int,res,Poly,const,简单,return,Deg
From: https://www.cnblogs.com/Delov/p/16457703.html