推一下式子发现是裸的FFT,$ans[k]=\sum_{i}\sum_{j}[i+j=k]a[i]*C_{m-1+j}^{j}$

比较坑爹的就是这个模数,于是我们上任意模数的FFT

任意模数的FFT目的就是降低卷积中的元素上界,我们设$P=\lfloor \sqrt{mod} \rfloor$,

我们将原函数中的系数变成两个$a1[i]=a[i]/P,a2[i]=a[i]%P,b1[i]=b[i]/P,b2[i]=b[i]%P$

这样我们新卷积出来的值的上限是$n*mod$,

$P^2$的系数是$a1*b1$,$P$的系数是$a1*b2+a2*b1$,$1$的系数是$a2*b2$,然后我们再分别卷积,最后统计答案即可

一开始炸精了。。改成预处理单位复数根就好了。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define mod 1000000007
#define MAXN 131072
using namespace std;
const double pi=acos(-1.0);
const int P=;
struct cmx{
double x,y;
cmx(){}
cmx(double a,double b){x=a,y=b;}
cmx operator + (cmx a){return cmx(x+a.x,y+a.y);}
cmx operator - (cmx a){return cmx(x-a.x,y-a.y);}
cmx operator * (cmx a){return cmx(x*a.x-y*a.y,x*a.y+y*a.x);}
cmx operator / (double a){return cmx(x/a,y/a);}
}A[MAXN],B[MAXN],C[MAXN],D[MAXN],E[MAXN],F[MAXN],G[MAXN],wn[MAXN],inv[MAXN];
int n,m,N,rev[MAXN];
long long ans[MAXN],a[MAXN],b[MAXN];
void fft(cmx *a,int o, cmx *wn){
register int i,j,k;
cmx t;
for(i=;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(k=;k<=N;k<<=)
for(j=;j<N;j+=k)
for(i=;i<(k>>);i++){
t=wn[N/k*i]*a[i+j+(k>>)];
a[i+j+(k>>)]=a[i+j]-t;
a[i+j]=a[i+j]+t;
}
if(o==-)for(i=;i<N;i++)a[i]=a[i]/N;
}
void FFT(long long *a,long long *b,long long *ans){
register int i;
for(i=;i<N;i++){
A[i]=cmx(a[i]/P,);
B[i]=cmx(a[i]%P,);
C[i]=cmx(b[i]/P,);
D[i]=cmx(b[i]%P,);
}
fft(A,,wn);fft(B,,wn);fft(C,,wn);fft(D,,wn);
for(i=;i<N;i++){
E[i]=A[i]*C[i];
F[i]=A[i]*D[i]+B[i]*C[i];
G[i]=B[i]*D[i];
}
fft(E,-,inv);fft(F,-,inv);fft(G,-,inv);
register long long tmp;
for(i=;i<n;i++){
tmp=1ll*round(E[i].x);
ans[i]=tmp%mod*P%mod*P%mod;
tmp=1ll*round(F[i].x);
(ans[i]+=tmp%mod*P%mod)%=mod;
(ans[i]+=1ll*round(G[i].x))%=mod;
}
}
long long qp(long long a,int b){
long long c=;
while(b){
if(b&)c=c*a%mod;
a=a*a%mod; b>>=;
}return c;
}
int main(){
scanf("%d%d",&n,&m);
register int i;
for(i=;i<n;i++)scanf("%lld",&a[i]);
b[]=;
for(i=;i<n;i++)
b[i]=1ll*b[i-]*(m-+i)%mod*qp(i,mod-)%mod;
for(N=;N<(n<<);N<<=);
for(i=;i<N;i++){
if(i&)rev[i]=(rev[i>>]>>)|(N>>);
else rev[i]=rev[i>>]>>;
}
for(i=;i<N;i++)
wn[i]=cmx(cos(*pi/N*i),sin(*pi/N*i)),
inv[i]=cmx(cos(*pi/N*i),-sin(*pi/N*i));
FFT(a,b,ans);
for(i=;i<n;i++)printf("%lld\n",ans[i]);
return ;
}

最新文章

  1. js 动态添加行,删除行,并获得select中值赋予 input
  2. nginx安装配置+清缓存模块安装
  3. Java中文档制作与继承
  4. (转) TensorFlow深度学习,一篇文章就够了
  5. JSBinding + SharpKit / Important Notes
  6. vi 在行首尾添加字符串
  7. Socket解决粘包问题1
  8. java操作DBF的使用
  9. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
  10. 上这个资源网站,让你轻松无忧找mac软件资源
  11. 如何在github上搭建网站?
  12. JVM系列3:类加载机制
  13. ext4.2常用的几种弹框
  14. JavaScript类继承, 用什么方法好
  15. 【Tomcat】配置Web界面管理
  16. 《C++标准程序库》笔记之四
  17. [buaa-SE-2017]结对项目-数独程序扩展
  18. 20162318 2018-2019-2《网络对抗技术》Exp1 PC平台逆向破解
  19. ftp 命令行操作 经常使用命令
  20. CentOS 6.5安装KVM实践

热门文章

  1. Java IO学习--(二)文件
  2. oracle超出打开游标的最大数的原因和解决方案
  3. Memcache 运行情况
  4. MySQL 中索引的限制
  5. Javac的实现过程
  6. python 之路,200行Python代码写了个打飞机游戏!
  7. 【转】H.264RTP封包原理
  8. Dubbo分布式服务框架入门使用
  9. 高通spi 屏幕 -lk代码分析
  10. 5月第2周业务风控关注 | 央行:严禁未经授权认可的APP接入征信系统