bzoj4555(多项式求逆解法)

//和以前写的fft不太一样,可能是因为要取模??
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=,maxn=;
int mx,n,m,inv[maxn],a[maxn],b[maxn],c[maxn],na[maxn],w[][maxn],pos[maxn];
int qmi(int x,int y){
int t=;
for(;y;y>>=,x=(ll)x*x%mod)if(y&)t=(ll)t*x%mod;
return t;
}
void pre(int n){
int i,x=qmi(,(mod-)/n);//以前这里的取值都和mod无关啊,取了模了不一样了?
w[][]=w[][]=;
for(int i=;i<n;++i)w[][i]=w[][n-i]=(ll)w[][i-]*x%mod;
for(int i=;i<n;++i){
pos[i]=pos[i>>]>>;
if(i&)pos[i]|=n>>;
}
}
void fnt(int *a,int n,int flag){
if(n>mx)mx=n;
int i,j,k,l,x,u,v;
for(i=;i<n;++i)na[pos[i]]=a[i];
memcpy(a,na,sizeof(int)*n);
for(k=;k<n;k<<=){
for(i=,x=n/k>>;i<n;i+=k<<)
for(j=i,l=;j<i+k;++j,l+=x){
u=a[j];v=(ll)a[j+k]*w[flag][l]%mod;
a[j]=(u+v)%mod;a[j+k]=(u-v+mod)%mod;
}
}
if(flag){
x=qmi(n,mod-);
for(i=;i<n;++i)a[i]=(ll)a[i]*x%mod;
}
}
void solve_inv(int *a,int *b,int n){
if(n==){b[]=qmi(a[],mod-);return;}
int i;solve_inv(a,b,n>>);
memcpy(c,a,sizeof(int)*n);memset(c+n,,sizeof(int)*n);
pre(n<<);
fnt(b,n<<,);fnt(c,n<<,);
for(i=;i<(n<<);++i)b[i]=(-(ll)b[i]*c[i]%mod+mod)*b[i]%mod;
fnt(b,n<<,);memset(b+n,,sizeof(int)*n);
}
int main(){
int i,n;scanf("%d",&n);
inv[]=inv[]=a[]=m=;
while(m<=n)m<<=;
for(int i=;i<=n;++i)inv[i]=mod-(ll)inv[mod%i]*(mod/i)%mod;
for(int i=;i<=n;++i)inv[i]=(ll)inv[i-]*inv[i]%mod;
for(int i=;i<=n;++i)a[i]=((mod-inv[i])<<)%mod;
solve_inv(a,b,m);
int ans=b[n];
for(int i=n;i;--i)ans=((ll)ans*i+b[i-])%mod;
printf("%d\n",ans);
return ;
}

学习地址:http://blog.csdn.net/lych_cys/article/details/51512278

上一篇:atitit.提升开发效率---MDA 软件开发方式的革命(4)----编辑表单建模


下一篇:弹框勾选datatable中的数据,点击保存后添加到另一个表中,同一个页面