模板
$ n^2 $ 多项式
const int N=1e6+7,mod=998244353;
inline void add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
inline int qpow(int a,int b){
int res=1;
for(;b;b>>=1,a=1ll*a*a%mod)
if(b&1)res=1ll*res*a%mod;
return res;
}
struct poly{
int n,a[N];
poly(int _n=0){n=_n,memset(a,0,sizeof(a));}
int& operator [](int i){return a[i];}
void out(){
printf("%d",a[0]);
for(int i=1;i<=n;i++){
if(!a[i])continue;
printf("+");if(a[i]>1)printf("%d",a[i]);
printf("x");if(i>1)printf("^%d",i);
}
puts("");
}
void rollback(){while(!a[n] && n)n--;}
poly operator +(poly q) const {
poly t(max(n,q.n));
for(int i=0;i<=n;i++)t[i]=a[i];
for(int i=0;i<=q.n;i++)add(t[i],q[i]);
return t.rollback(),t;
}
poly operator -(poly q) const {
poly t(max(n,q.n));
for(int i=0;i<=n;i++)t[i]=a[i];
for(int i=0;i<=q.n;i++)add(t[i],mod-q[i]);
return t.rollback(),t;
}
poly operator *(poly q) const {
poly t(n+q.n);
for(int i=0;i<=n;i++)
for(int j=0;j<=q.n;j++)
add(t[i+j],1ll*a[i]*q[j]%mod);
return t.rollback(),t;
}
poly inv(){
poly t(n);
t[0]=qpow(a[0],mod-2);
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++)add(t[i],mod-1ll*t[j]*a[i-j]%mod);
t[i]=1ll*t[i]*t[0]%mod;
}
return t.rollback(),t;
}
pair<poly,poly> div(poly q){
poly t(n-q.n),r=*this;
for(int i=n;i>=q.n;i--){
t[i-q.n]=1ll*r[i]*qpow(q[q.n],mod-2)%mod;
for(int j=i;j>=i-q.n;j--)add(r[j],mod-1ll*q[j-i+q.n]*t[i-q.n]%mod);
}
t.rollback(),r.rollback();
return {t,r};
}
poly operator /(poly q){
if(n<q.n)return poly(0);
return div(q).first;
}
poly operator %(poly q){
if(n<q.n)return *this;
return div(q).second;
}
poly operator ^(int k){
poly t=poly(0),r=*this;t[0]=1;
while(k){
if(k&1){t=t*r;if(t.n>n)t.n=n;}
r=r*r,k>>=1;if(r.n>n)r.n=n;
}
return t;
}
};
vector 版:
struct poly {
vector<int>a;
poly(int n=1, int x=0) :a(n) {a[0]=x;}
inline void resize(int n) {a.resize(n);}
inline int size() {return a.size();}
inline void chk(int n) {if (a.size()>n) a.resize(n);}
int& operator [](int i) {return a[i];}
inline void push_back(int x) {a.push_back(x);}
inline void pop_back() {a.pop_back();}
poly& operator +=(poly q) {
if (a.size()<q.size()) a.resize(q.size());
for (int i=0; i<q.size(); i++) inc(a[i], q[i]);
return *this;
}
poly& operator -=(poly q) {
if (a.size()<q.size()) a.resize(q.size());
for (int i=0; i<q.size(); i++) dec(a[i], q[i]);
return *this;
}
poly operator +(poly q) {poly t=*this; t+=q; return t;}
poly operator -(poly q) {poly t=*this; t-=q; return t;}
poly operator *(poly q) {
poly t(a.size()+q.size()-1);
for (int i=0; i<a.size(); i++)
for (int j=0; j<q.size(); j++) inc(t[i+j], (ll)a[i]*q[j]%mod);
return t;
}
poly& operator *=(poly q) {return *this=*this*q;}
};
高精度($ +,-,\times $):
struct Int{
vector<int>a;
Int(int n=1){a.resize(n);}
inline int size(){return a.size();}
inline int& back(){return a.back();}
inline void push_back(int x){a.push_back(x);}
inline void resize(int n){a.resize(n);}
int& operator [](int i){return a[i];}
Int operator =(int x){a.clear(),a.push_back(x%10),x/=10;while(x)a.push_back(x%10),x/=10;return *this;}
inline void out(char c=10){for(int i=a.size()-1;~i;i--)printf("%d",a[i]);putchar(c);}
};
inline Int zh(int x){Int a;return a=x;}
Int operator +(Int a,Int b){
if(a.size()<b.size())swap(a,b);
for(int i=0;i<b.size();i++)a[i]+=b[i];
for(int i=0;i<a.size()-1;i++)if(a[i]>9)a[i]-=10,a[i+1]++;
if(a.back()>9)a.back()-=10,a.push_back(1);
return a;
}
Int operator -(Int a,Int b){
if(a.size()<b.size())swap(a,b);
for(int i=0;i<b.size();i++)a[i]-=b[i];
for(int i=0;i<a.size()-1;i++)if(a[i]<0)a[i]+=10,a[i+1]--;
return a;
}
Int operator *(Int a,Int b){
Int c(a.size()+b.size()-1);
for(int i=0;i<a.size();i++)
for(int j=0;j<b.size();j++)
c[i+j]+=a[i]*b[j];
for(int i=0;i<c.size()-1;i++)c[i+1]+=c[i]/10,c[i]%=10;
while(c.back()>9)c.push_back(c.back()/10),c[c.size()-2]%=10;
return c;
}