多项式总结(STAGE 1)
这么难的专题居然只给了这么短时间。。。
然而在NC的教导之下还是有一定的收获的。
附带一个垃圾博客:-1
按照习惯,堆砌结论而不加证明。
Section1 导数:
基本形式:$f'(x)=\lim\limits_{\Delta x\rightarrow 0}\frac{f(x+\Delta x)-f(x)}{\Delta x}$
一次函数:$f(x)=ax+b \rightarrow f'(x)=a$
幂函数:$f(x)=x^n \rightarrow f'(x)=nx^{n-1}$
正弦函数:$\lim\limits_{x \rightarrow 0}sin(x)=x $,得到$f(x)=sin(ax+b) \rightarrow f'(x)=a \ cos(ax+b)$
余弦函数:$\lim\limits_{x \rightarrow 0}cos(x)=1 $,得到$f(x)=cos(ax+b) \rightarrow f'(x)=-a \ sin(ax+b)$
指数函数:$e=\lim\limits_{n \rightarrow + \infty} (1+ \frac{1}{n})^n$,得到$f(x)=a^x \rightarrow f'(x)=a^x ln \ a$
特别的,自然对数的指数函数:$f(x)=e^x \rightarrow e^x$。即$e$可以无限求导。
对数函数:$f(x)=log_a x \rightarrow f'(x)=\frac{1}{xlna}$
特别的,自然对数的对数函数:$f(x)=\frac{1}{x}$
运算法则:加法,减法,常数乘法。
乘法:设$h(x)=f(x)g(x)$,有$h'(x)=f'(x)g(x)+f(x)g'(x)$
除法:设$h(x)=\frac{f(x)}{g(x)}$ ,有$h'(x)=\frac{f'(x)g(x)-g'(x)f(x)}{g^2(x)}$
复合函数:设$h(x)=f(g(x))$,有$h'(x)=f'(g(x))g'(x)$
逆运算——积分:
多项式不定积分:$F'(x)=f(x) ,f(x)=ax^k \rightarrow F(x)=\frac{a}{k+1} x^{k+1}$
Section2 导数在多项式的应用:
泰勒展开:$f(x)=\sum\limits_{i=0}^{n}\frac{f^{(i)}(x_0)(x-x_0)^i}{i!}$
麦克劳林公式:$f(x)=\sum\limits_{i=0}^{n}\frac{f^{(i)}(0)x^i}{i!}$,是泰勒展开在$x_0$取0时的特殊形式。
级数求和公式:运用泰勒展开,讲简单形式与和式相互转化。
例如《在美妙的数学王国中畅游》一题中,运用泰勒展开,讲难以运算并求和的sin和exp函数都可以展开为多项式。
而多项式是可以直接相加的与自变量x无关,所以就可以用数据结构维护系数。
$e^x=\sum\limits_{i=0}^{\infty} \frac{x^i}{i!}$
$\frac{1}{1-x}=\sum\limits_{i=0}^{\infty} x^i$
$\frac{1}{1+x}=\sum\limits_{i=0}^{\infty} (-x)^i$
$ln(1+x)= - \sum\limits_{i=1}^{\infty} \frac{(-x)^i}{i} $
$sin(x)=\sum\limits_{i=0}^{\infty} (-1)^{i+1} \times \frac{x^{2i-1}}{(2i-1)!}$
$cos(x)=\sum\limits_{i=0}^{\infty} (-1)^i \times \frac{x^{2i}}{(2i)!}$
牛顿迭代:利用泰勒展开逼近函数零点。
多项式牛顿迭代:
若已经求出$G_0(x)$,使$F(G_0(x)) \equiv 0(mod x^n)$,
则设$G(x) \equiv G_0(x)-\frac{F(G_0(x))}{F'(G_0(x))}(mod x^{2n})$,
有$F(G(x)) \equiv 0 (mod x^{2n})$
迭代使精度翻倍。应用于多项式除法。
多项式全家桶:(洛谷题库搜索“多项式模板”)
模板区:
#include<cstdio>
#include<cmath>
using namespace std;
#define pi 3.141592653589793238462643383279
#define S 262144
#define mod 1000000007
#define ll long long
const int s=(<<)-;
struct cp{double r,i;
cp operator+(cp x){return (cp){r+x.r,i+x.i};}
cp operator-(cp x){return (cp){r-x.r,i-x.i};}
cp operator*(cp x){return (cp){r*x.r-i*x.i,x.r*i+r*x.i};}
void operator=(int a){r=a;i=;}
}a1[S],a2[S],b1[S],b2[S],x2[S],x1[S],x0[S],o[][][S],R,X,Y;
int rev[S],n,A[S],inv[S],len=,bit,a[S],b[S],c[S],d[S];
int pow(int b,int t,int a=){for(;t;t>>=,b=1ll*b*b%mod)if(t&)a=1ll*a*b%mod;return a;}
ll r(cp x){return (ll)(floor(x.r+0.5))%mod;}
void FFT(cp *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)R=a[i],a[i]=a[rev[i]],a[rev[i]]=R;
for(int mid=,p=;mid<len;mid<<=,p++)for(int i=;i<len;i+=mid<<)for(int j=i;j<i+mid;++j)
X=a[j],Y=a[j+mid]*o[opt>][p][j-i],a[j]=X+Y,a[j+mid]=X-Y;
if(opt==-)for(int i=;i<len;++i)a[i].r/=len;
}
void MTT(int *a,int *b,int *c){
for(int i=;i<len;++i)a1[i]=a[i]&s,a2[i]=a[i]>>,b1[i]=b[i]&s,b2[i]=b[i]>>;
FFT(a1,);FFT(a2,);FFT(b1,);FFT(b2,);
for(int i=;i<len;++i)x2[i]=b2[i]*a2[i],x0[i]=b1[i]*a1[i],x1[i]=b2[i]*a1[i]+b1[i]*a2[i];
FFT(x2,-);FFT(x1,-);FFT(x0,-);
for(int i=;i<len;++i)c[i]=(((r(x2[i])<<)+(r(x1[i])<<)+r(x0[i]))%mod+mod)%mod;
}
void divide(int n){
if(n==){inv[]=pow(A[],mod-);return;}
divide(n+>>);len=;while(len<n<<)len<<=;
for(int i=;i<len;++i)a[i]=(i<n)*A[i],b[i]=inv[i]*(i<n+>>);
MTT(a,b,c);MTT(c,b,d);
for(int i=;i<len;++i)inv[i]=(b[i]*-d[i]+mod)%mod;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;++i)scanf("%d",&A[i]);
while(len<n<<)len<<=;
for(int i=;<<i<len;++i)for(int j=;j<<<i;++j)
o[][i][j]=(cp){cos(pi/(<<i)*j),sin(pi/(<<i)*j)},
o[][i][j]=(cp){cos(pi/(<<i)*j),-sin(pi/(<<i)*j)};
divide(n);for(int i=;i<n;++i)printf("%d ",inv[i]);puts("");
}
求逆inv(加强:任意模数)
#include<cstdio>
#define int long long
#define mod 998244353
#define S 1<<20
int rev[S],F[S],G[S],Q[S],n,m,len=,ra[S],rb[S],iG[S],RA[S],RB[S];
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void NTT(int *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)/mid/*opt+mod-);i<len;i+=mid<<)
for(int j=i,w=,x,y;j<i+mid;++j,w=w*t%mod)
x=a[j],y=a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-);i<len;++i)a[i]=a[i]*iv%mod;
}
void re(int *a,int n){for(int i=,j=n-;i<j;++i,--j)a[i]^=a[j]^=a[i]^=a[j];}
void pt(int *a,int n){for(int i=;i<n;++i)printf("%lld ",a[i]);puts("");}
void mul(int *a,int la,int *b,int lb,int *c){
len=;while(len<la+lb<<)len<<=;
for(int i=;i<len;++i)ra[i]=rb[i]=;
for(int i=;i<la;++i)ra[i]=a[i];
for(int i=;i<lb;++i)rb[i]=b[i];
NTT(ra,);NTT(rb,);
for(int i=;i<len;++i)c[i]=ra[i]*rb[i]%mod;
NTT(c,-);
}
void mul(int *a,int *b,int *c){
for(int i=;i<len;++i)ra[i]=a[i],rb[i]=b[i];
NTT(ra,);NTT(rb,);
for(int i=;i<len;++i)c[i]=ra[i]*rb[i]%mod;
NTT(c,-);
}
void inv(int *a,int x,int *b){
if(x==){b[]=pow(a[],mod-);return;}
inv(a,x+>>,b);len=;while(len<x<<)len<<=;
for(int i=;i<len;++i)RA[i]=RB[i]=;
for(int i=;i<x;++i)RA[i]=a[i];
for(int i=;i<x+>>;++i)RB[i]=b[i];
mul(RA,RB,RA);mul(RA,RB,RA);
for(int i=;i<x;++i)b[i]=(RB[i]+RB[i]-RA[i]+mod)%mod;
}
main(){
scanf("%lld%lld",&n,&m);n++;m++;
for(int i=;i<n;++i)scanf("%lld",&F[i]);
for(int i=;i<m;++i)scanf("%lld",&G[i]);
re(F,n);re(G,m);inv(G,n-m+,iG);mul(F,n,iG,n-m+,Q);re(Q,n-m+);pt(Q,n-m+);
re(G,m);mul(Q,n-m+,G,m,Q);re(F,n);
for(int i=;i<m-;++i)printf("%lld ",(F[i]-Q[i]+mod)%mod);puts("");
}
除法
#include<cstdio>
#include<map>
using namespace std;
map<int,int>M;
#define mod 998244353
#define S 1<<19
int pow(int b,int t,int a=){for(;t;t>>=,b=1ll*b*b%mod)if(t&)a=1ll*a*b%mod;return a;}
int BSGS(int x){
int k=pow(,),I=pow(,mod-);
for(int i=,p=;i<mod;i+=,p=1ll*p*k%mod)M[p]=i;
for(int i=,p=;i<;++i,p=1ll*I*p%mod)if(M.find(1ll*x*p%mod)!=M.end())
return i+M[1ll*x*p%mod];
}
int rev[S],a[S],s[S],A[S],b[S],ra[S],rb[S],R[S],len,n,r[S];
#define mat len=1;while(len<n<<1)len<<=1
void NTT(int *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)/mid/*opt+mod-);i<len;i+=mid<<)
for(int j=i,w=,x,y;j<i+mid;++j,w=1ll*w*t%mod)
x=a[j],y=1ll*a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-);i<len;++i)a[i]=1ll*a[i]*iv%mod;
}
void mul(int *a,int *b,int *c,int opt=){
NTT(a,);NTT(b,);
for(int i=;i<len;++i)c[i]=1ll*a[i]*b[i]%mod;
NTT(c,-);if(opt)NTT(b,-);
}
void inv(int n){
if(n==){r[]=pow(b[],mod-);return;}
inv(n+>>);mat;
for(int i=;i<len;++i)ra[i]=i<n?b[i]:,rb[i]=i<n+>>?r[i]:;
mul(ra,rb,R);mul(R,rb,R);
for(int i=;i<len;++i)r[i]=(0ll+rb[i]+rb[i]-R[i]+mod)%mod;
}
void sqr(int n){
if(n==){s[]=pow(,BSGS(A[])/);if(s[]>mod-s[])s[]=mod-s[];return;}
sqr(n+>>);mat;
for(int i=;i<len;++i)a[i]=i<n?A[i]:,b[i]=i<n+>>?s[i]:;
inv(len>>);mat;for(int i=len>>;i<len;++i)r[i]=;
mul(a,r,R,);for(int i=;i<len;++i)s[i]=(b[i]+R[i])*499122177ll%mod;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;++i)scanf("%d",&A[i]);
sqr(n);
for(int i=;i<n;++i)printf("%d ",s[i]);puts("");
}
开根sqr(加强:不保证a0=1)
#include<cstdio>
#define int long long
#define mod 998244353
#define S 1<<19
int n,len,rev[S],A[S],iA[S],ra[S],rb[S],Ra[S],Rb[S],ans[S],l1[S],l2[S];
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void deriv(int *a,int n,int *b){for(int i=;i<n-;++i)b[i]=a[i+]*(i+)%mod;b[n-]=;}
void integ(int *a,int n,int *b){for(int i=n-;i;--i)b[i]=a[i-]*pow(i,mod-)%mod;b[]=;}
void NTT(int *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)/mid/*opt+mod-);i<len;i+=mid<<)
for(int j=i,w=,x,y;j<i+mid;++j,w=w*t%mod)
x=a[j],y=a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-);i<len;++i)a[i]=a[i]*iv%mod;
}
void pt(int *a,int n=len){for(int i=;i<n;++i)printf("%lld ",a[i]);puts("");}
void mat(int x){len=;while(len<x)len<<=;}
void mul(int *a,int *b,int *c){
for(int i=;i<len;++i)Ra[i]=a[i],Rb[i]=b[i];
NTT(Ra,);NTT(Rb,);for(int i=;i<len;++i)c[i]=Ra[i]*Rb[i]%mod;NTT(c,-);
}
void inv(int *a,int n,int *b){
if(n==){b[]=pow(a[],mod-);return;}
inv(a,n+>>,b);mat(n<<);
for(int i=;i<len;++i)ra[i]=rb[i]=;
for(int i=;i<n;++i)ra[i]=a[i];
for(int i=;i<n+>>;++i)rb[i]=b[i];
mul(ra,rb,ra);mul(ra,rb,ra);
for(int i=;i<n;++i)b[i]=(rb[i]+rb[i]-ra[i]+mod)%mod;
}
void ln(int *a,int *b,int n){inv(a,n,l1);deriv(a,n,l2);mat(n<<);mul(l1,l2,b);integ(b,n,b);}
main(){
scanf("%lld",&n);
for(int i=;i<n;++i)scanf("%lld",&A[i]);
ln(A,ans,n);
for(int i=;i<n;++i)printf("%lld ",ans[i]);puts("");
}
自然对数ln
#include<cstdio>
#define int long long
#define mod 998244353
#define S 1<<19
int rev[S],len,n,A[S],ans[S];
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void NTT(int *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)/mid/*opt+mod-);i<len;i+=mid<<)
for(int j=i,w=,x,y;j<i+mid;++j,w=w*t%mod)
x=a[j],y=a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-);i<len;++i)a[i]=a[i]*iv%mod;
}
void pt(int *a,int n=len){for(int i=;i<n;++i)printf("%lld ",a[i]);puts("");}
void mat(int x){len=;while(len<x)len<<=;}
void deriv(int *a,int n,int *b){for(int i=;i<n;++i)b[i-]=a[i]*i%mod;b[n-]=;}
void integ(int *a,int n,int *b){for(int i=;i<n;++i)b[i]=a[i-]*pow(i,mod-)%mod;b[]=;}
int r1[S],r2[S];
void mul(int *a,int *b,int *c){
for(int i=;i<len;++i)r1[i]=a[i],r2[i]=b[i];
NTT(r1,);NTT(r2,);for(int i=;i<len;++i)c[i]=r1[i]*r2[i]%mod;NTT(c,-);
}
int v1[S],v2[S];
void inv(int *a,int n,int *b){
if(n==){b[]=pow(a[],mod-);return;}
inv(a,n+>>,b);mat(n<<);
for(int i=;i<len;++i)v1[i]=v2[i]=;
for(int i=;i<n;++i)v1[i]=a[i];
for(int i=;i<n+>>;++i)v2[i]=b[i];
mul(v1,v2,v1);mul(v1,v2,v1);
for(int i=;i<n;++i)b[i]=(v2[i]+v2[i]-v1[i]+mod)%mod;
}
int n1[S],n2[S];
void ln(int *a,int n,int *b){deriv(a,n,n1);inv(a,n,n2);mat(n<<);mul(n1,n2,n1);integ(n1,n,b);}
int e[S];
void exp(int *a,int n,int *b){
if(n==){b[]=;return;}
exp(a,n+>>,b);ln(b,n,e);
for(int i=;i<n;++i)e[i]=(a[i]-e[i]+mod)%mod;e[]++;
mat(n<<);mul(b,e,b);
for(int i=n;i<len;++i)b[i]=;
}
main(){
scanf("%lld",&n);
for(int i=;i<n;++i)scanf("%lld",&A[i]);
exp(A,n,ans);pt(ans,n);
}
自然对数幂exp
#include<cstdio>
#define int long long
#define mod 998244353
#define S 1<<20
int rev[S],len,n,k,c,A[S],r1[S],r2[S],v1[S],v2[S],e[S],n1[S],n2[S],p[S],ans[S],I;
int pow(int b,int t,int a=){for(;t;t>>=,b=b*b%mod)if(t&)a=a*b%mod;return a;}
void NTT(int*a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)/mid/*opt+mod-);i<len;i+=mid<<)
for(int j=i,x,y,w=;j<i+mid;++j,w=w*t%mod)
x=a[j],y=a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-);i<len;++i)a[i]=a[i]*iv%mod;
}
void pt(int*a,int n=len){for(int i=;i<n;++i)printf("%lld ",a[i]);puts("");}
void mat(int x){len=;while(len<x)len<<=;}
void deriv(int*a,int n,int*b){for(int i=;i<n;++i)b[i]=a[i+]*(i+)%mod;}
void integ(int*a,int n,int*b){for(int i=;i<n;++i)b[i]=a[i-]*pow(i,mod-)%mod;b[]=;}
void mul(int*a,int*b,int*c){
for(int i=;i<len;++i)r1[i]=a[i],r2[i]=b[i];
NTT(r1,);NTT(r2,);for(int i=;i<len;++i)c[i]=r1[i]*r2[i]%mod;NTT(c,-);
}
void inv(int*a,int n,int*b){
if(n==){b[]=pow(a[],mod-);return;}
inv(a,n+>>,b);mat(n<<);
for(int i=;i<len;++i)v1[i]=v2[i]=;
for(int i=;i<n;++i)v1[i]=a[i];
for(int i=;i<n+>>;++i)v2[i]=b[i];
mul(v1,v2,v1);mul(v1,v2,v1);
for(int i=;i<n;++i)b[i]=(v2[i]+v2[i]-v1[i]+mod)%mod;
}
void ln(int*a,int n,int*b){
deriv(a,n,n1);inv(a,n,n2);mat(n<<);
for(int i=n;i<len;++i)n1[i]=n2[i]=;
mul(n1,n2,n1);integ(n1,n,b);
}
void exp(int*a,int n,int*b){
if(n==){b[]=;return;}
exp(a,n+>>,b);ln(b,n,e);
for(int i=;i<n;++i)e[i]=(a[i]-e[i]+mod)%mod;e[]++;
mat(n<<);for(int i=n;i<len;++i)e[i]=;mul(e,b,b);
}
void pow(int*a,int n,int*b,int k){ln(a,n,p);for(int i=;i<n;++i)p[i]=p[i]*k%mod;exp(p,n,b);}
main(){
scanf("%lld%lld",&n,&k);
for(int i=,x=;i<n;++i)scanf("%lld",&A[i-c]),x*=(!A[i-c]),c+=x;
I=pow(A[],mod-);for(int i=;i<n-c;++i)A[i]=A[i]*I%mod;pow(A,n-c,ans,k);
I=pow(I,(mod-)*k);for(int i=;i<n-c;++i)ans[i]=ans[i]*I%mod;
for(int i=;i<c*k&&i<n;++i)printf("0 ");
for(int i=;i<n-c*k;++i)printf("%lld ",ans[i]);puts("");
}
快速幂pow(加强:不保证a0=1)
Section 3:各种卷积性变换
FFT:运用复数单位根进行插值变换
NTT:运用原根进行插值变换
FWT:运用位运算卷积(与/或/异或)
MTT:任意模数NTT
#include<cstdio>
#define int long long
#define S 262144
#define m1 167772161
#define m2 998244353
#define m3 1004535809
const int M=1ll*m1*m2,R=m2%m1;
int mod,len=,rev[S],a[S],b[S],ra[S],rb[S],ans[][S],n,m,p,c;
int pow(int b,int t,int m,int a=){for(;t;t>>=,b=b*b%m)if(t&)a=a*b%m;return a;}
int mul(int x,int y,int a=){for(;y;y>>=,x=(x+x)%M)if(y&)a=(a+x)%M;return a;}
void NTT(int *a,int opt){
for(int i=;i<len;++i)if(rev[i]>i)a[i]^=a[rev[i]]^=a[i]^=a[rev[i]];
for(int mid=;mid<len;mid<<=)
for(int i=,t=pow(,(mod-)//mid*opt+mod-,mod);i<len;i+=mid<<)
for(int j=i,w=,x,y;j<i+mid;++j,w=w*t%mod)
x=a[j],y=a[j+mid]*w%mod,a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
if(opt==-)for(int i=,iv=pow(len,mod-,mod);i<len;++i)a[i]=a[i]*iv%mod;
}
void solve(int x){mod=x;
for(int i=;i<len;++i)a[i]=ra[i],b[i]=rb[i];
NTT(a,);NTT(b,);
for(int i=;i<len;++i)ans[c][i]=a[i]*b[i]%mod;
NTT(ans[c],-);c++;
}
int cal(int a,int b,int c){
int x=((mul(a*m2%M,pow(R,m1-,m1)))+mul(b*m1%M,pow(m1,m2-,m2)))%M;
int y=((c-x)%m3+m3)%m3*pow(M%m3,m3-,m3)%m3%p;return (M%p*y+x)%p;
}
main(){
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=;i<=n;++i)scanf("%lld",&ra[i]);
for(int i=;i<=m;++i)scanf("%lld",&rb[i]);
while(len<=n+m+)len<<=;
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
solve(m1);solve(m2);solve(m3);
for(int i=;i<=n+m;++i)printf("%lld ",cal(ans[][i],ans[][i],ans[][i]));
}
三模数NTT->MTT
#include<cstdio>
#include<cmath>
using namespace std;
#define pi 3.141592653589793238462643383279
#define S 262144
#define mod 1000000007
#define ll long long
const int s=(<<)-;
struct cp{double r,i;
cp operator+(cp x){return (cp){r+x.r,i+x.i};}
cp operator-(cp x){return (cp){r-x.r,i-x.i};}
cp operator*(cp x){return (cp){r*x.r-i*x.i,x.r*i+r*x.i};}
void operator=(int a){r=a;i=;}
}a1[S],a2[S],b1[S],b2[S],o[][][S],X,Y,A1,A2,B1,B2;
int rev[S],n,A[S],inv[S],len=,bit,a[S],b[S],c[S];
int pow(int b,int t,int a=){for(;t;t>>=,b=1ll*b*b%mod)if(t&)a=1ll*a*b%mod;return a;}
ll r(cp x){return (ll)(floor(x.r+0.5))%mod;}
void FFT(cp *a,int opt){
for(int i=;i<len;++i)rev[i]=rev[i>>]>>|(i&?len>>:);
for(int i=;i<len;++i)if(rev[i]>i)X=a[i],a[i]=a[rev[i]],a[rev[i]]=X;
for(int mid=,p=;mid<len;mid<<=,p++)for(int i=;i<len;i+=mid<<)for(int j=i;j<i+mid;++j)
X=a[j],Y=a[j+mid]*o[opt>][p][j-i],a[j]=X+Y,a[j+mid]=X-Y;
if(opt==-)for(int i=;i<len;++i)a[i].r/=len;
}
void MTT(int *a,int *b,int *c){
for(int i=;i<len;++i)a1[i]=a[i]&s,a2[i]=a[i]>>,b1[i]=b[i]&s,b2[i]=b[i]>>;
FFT(a1,);FFT(a2,);FFT(b1,);FFT(b2,);
for(int i=;i<len;++i)A1=a1[i],B1=b1[i],A2=a2[i],B2=b2[i],
a1[i]=B2*A2,a2[i]=B1*A1,b1[i]=B2*A1+B1*A2;
FFT(b1,-);FFT(a2,-);FFT(a1,-);
for(int i=;i<len;++i)c[i]=(((r(a1[i])<<)+(r(b1[i])<<)+r(a2[i]))%mod+mod)%mod;
}
void divide(int n){
if(n==){inv[]=pow(A[],mod-);return;}
divide(n+>>);len=;while(len<n<<)len<<=;
for(int i=;i<len;++i)a[i]=(i<n)*A[i],b[i]=inv[i]*(i<n+>>);
MTT(a,b,c);MTT(c,b,c);
for(int i=;i<len;++i)inv[i]=(b[i]*-c[i]+mod)%mod;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;++i)scanf("%d",&A[i]);
while(len<n<<)len<<=;
for(int i=;<<i<len;++i)for(int j=;j<<<i;++j)
o[][i][j]=(cp){cos(pi/(<<i)*j),sin(pi/(<<i)*j)},
o[][i][j]=(cp){cos(pi/(<<i)*j),-sin(pi/(<<i)*j)};
divide(n);for(int i=;i<n;++i)printf("%d ",inv[i]);puts("");
}
拆系数MTT
for(int i=;i<len;++i)for(int j=;j<len;j+=i)for(int k=j;k<j+i;++k)a[k+i]+=a[k]*opt;//or
for(int i=;i<len;++i)for(int j=;j<len;j+=i)for(int k=j;k<j+i;++k)a[k]+=a[k+i]*opt;//and
for(int i=;i<len;++i)for(int j=;j<len;j+=i)for(int k=j;k<j+i;++k)
a[k]+=a[k+i],a[k+i]=a[k]-a[k+i]*,a[k],a[k]/=(opt==-?:),a[k+i]/=(opt==-?:);//xor
FWT(or,and,xor)
Section 4:母函数
OGF:$F(x)=\sum\limits_{i=0}^{\infty}a_ix^i$。常用于组合。
EGF:$F(x)=\sum\limits_{i=0}^{\infty}\frac{a_i}{i!}x^i$。常用于排列。
主要就是用于把数列带入需要化简的式子,以便于进行多项式运算。
多项式总结(STAGE 1)的更多相关文章
- Spark DAGSheduler生成Stage过程分析实验
RDD.Action触发SparkContext.run,这里举最简单的例子rdd.count() /** * Return the number of elements in the RDD. */ ...
- NOIP2009多项式输出(水)【A004】
[A004]潜伏者[难度A]—————————————————————————————————————————————————————————————————————————— [题目要求] 一元 n ...
- 两个多项式相加 ( C++ )
实现两个多项式进行相加 不开辟空间 ( 这要求实现进行相加,代价为两个原链表将被修改) 分析: this>other 就把other当前结点放置在this之前 this<other 就th ...
- 程序设计入门——C语言 第7周编程练习 1多项式加法(5分)
第7周编程练习 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统 ...
- 一个简单的游戏开发框架(四.舞台Stage)
首先是StageManager类: class StageManager : public Singleton<StageManager> { friend class Singleton ...
- Rasterizer Stage(读书笔记3 --- Real-Time rendering)
rasterizer stage的目标:计算和设置每个像素的颜色.将屏幕空间的二维顶点和每个顶点的shading信息转换为屏幕上的像素. rasterizer stage可以分为几个阶段:triang ...
- Geometry Stage in Rendering pipeline (读书笔记2 --- Real-Time rendering)
Geometry Stage一般包含下面几个阶段 1. Model & View Transform(模型和视图变换) --- 模型空间--> 世界空间 模型变换:每个模型经过模型变换来 ...
- spark job, stage ,task介绍。
1. spark 如何执行程序? 首先看下spark 的部署图: 节点类型有: 1. master 节点: 常驻master进程,负责管理全部worker节点. 2. worker 节点: 常驻wor ...
- 用clock()函数计算多项式的运行时间
百度百科中定义clock():clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 简 ...
随机推荐
- 【CSS】381- 提升你的CSS选择器技巧
我已经使用CSS多年了,但直到最近我才深入研究了一下CSS选择器. 我为什么要这样做呢?我们都知道选择器,但麻烦的是随着时间的推移,很容易习惯于在每个项目中使用相同的可信任选择器来实现你需要做的事情. ...
- 搞懂toString()与valueOf()的区别
一.toString() 作用:toString()方法返回一个表示改对象的字符串,如果是对象会返回,toString() 返回 “[object type]”,其中type是对象类型. 二.valu ...
- 多线程之美5一 AbstractQueuedSynchronizer源码分析<一>
AQS的源码分析 目录结构 1.什么是CAS ? 2.同步器类结构 3.CLH同步队列 4.AQS中静态内部类Node 5.方法分析 5.1.acquire(int arg ) 5.2.rel ...
- tomcat启动内存溢出三种解决方案:java.lang.OutOfMemoryError:PermGen space解决办法
问题: 严重: Error waiting for multi-thread deployment of WAR files to completejava.util.concurrent.Execu ...
- rabbitmq~消息失败后重试达到 TTL放到死信队列(事务型消息补偿机制)
这是一个基于消息的分布式事务的一部分,主要通过消息来实现,生产者把消息发到队列后,由消费方去执行剩下的逻辑,而当消费方处理失败后,我们需要进行重试,即为了最现数据的最终一致性,在rabbitmq里,它 ...
- C#程序编写高质量代码改善的157个建议【16-19】[动态数组、循环遍历、对象集合初始化]
前言 软件开发过程中,不可避免会用到集合,C#中的集合表现为数组和若干集合类.不管是数组还是集合类,它们都有各自的优缺点.如何使用好集合是我们在开发过程中必须掌握的技巧.不要小看这些技巧,一旦在开 ...
- 魔术师发牌问题 -- python实现
问题描述 魔术师手中有A.2.3--J.Q.K十三张黑桃扑克牌.在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下).魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来, ...
- android只设置部分控件随着软键盘的出现而腾出空间
转载请标明出处:https://www.cnblogs.com/tangZH/p/12013685.html 在项目过程中,出现了一个需求,软键盘要顶起部分控件,而另一部分控件不动. 关于这种需求,我 ...
- 深度学习优质学习项目大放送!-AI Studio精选开源项目合集推荐
近期 在AI Studio上发现了不少优质的开源深度学习项目,从深度学习入门到进阶,涵盖了CV.NLP.生成对抗网络.强化学习多个研究方向,还有最新的动态图,都以NoteBook的方式直接开源出来,并 ...
- zuul网关
Zuul路由网关简介及基本使用 简介 Zuul API路由网关服务简介 请看上图,这里的API 路由网关服务 由Zuul实现,主要就是对外提供服务接口的时候,起到了请求的路由和过滤作用,也因此能够隐藏 ...