BZOJ2287: 【POJ Challenge】消失之物

来源:互联网 发布:python 自然语言理解 编辑:程序博客网 时间:2024/06/04 22:16

高兴的写了个FFT发现自己是最慢的几个… 思想固化…
非正解


维护一个前缀DPf[i][j]表示1~i凑出j的方案数,一个后缀DPg[i][j]表示i~n凑出j的方案数,去掉i就是f[i-1]和g[i+1]合并,用FFT卷积优化

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline int read(){    char c; int x;    while(!((c=getchar())>='0'&&c<='9'));    x=c-'0';    while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';    return x;}const int maxn = 2100;const int maxm = 2100;const double pi= acos(-1);struct E{    double x,y;    E(){}    E(double _x,double _y){x=_x;y=_y;}}zero,s1[maxn<<3],s2[maxn<<3],s3[maxn<<3],wn[maxn<<3]; int id[maxm<<3],N;inline E operator +(E x,E y){return E(x.x+y.x,x.y+y.y);}inline E operator -(E x,E y){return E(x.x-y.x,x.y-y.y);}inline E operator *(E x,E y){    return E(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}void pre_FFT(int n){    N=1; int ln=0; while(N<=(n<<1)) N<<=1,ln++;    for(int i=0;i<N;i++) id[i]=id[i>>1]>>1|((i&1)<<ln-1);    for(int m=2;m<=N;m<<=1)    {        int t=m>>1,tt=N/m;        for(int i=0;i<t;i++)        {            wn[i*tt]=E(cos(2*pi*i/m),sin(2*pi*i/m));            wn[N-i*tt]=E(cos(2*pi*i/m),sin(-2*pi*i/m));        }    }}void FFT(E *s,int sig){    for(int i=0;i<N;i++) if(i<id[i]) swap(s[i],s[id[i]]);    for(int m=2;m<=N;m<<=1)    {        int t=m>>1,tt=N/m;        for(int i=0;i<t;i++)        {            E w=sig==1?wn[i*tt]:wn[N-i*tt];            for(int j=i;j<N;j+=m)            {                E tx=s[j],ty=w*s[j+t];                s[j]=tx+ty;                s[j+t]=tx-ty;            }        }    }    if(sig==-1) for(int i=0;i<N;i++) s[i].x/=(double)N;}int n,m,a[maxn];int f[maxn][maxm],g[maxn][maxm];int main(){    n=read(),m=read();    for(int i=1;i<=n;i++) a[i]=read();    pre_FFT(m);    f[0][0]=1;    for(int i=1;i<=n;i++)    {        for(int j=0;j<=m;j++)        {            f[i][j]=f[i-1][j];            if(j>=a[i]) (f[i][j]+=f[i-1][j-a[i]])%=10;        }    }    g[n+1][0]=1;    for(int i=n;i>=1;i--)    {        for(int j=0;j<=m;j++)        {            g[i][j]=g[i+1][j];            if(j>=a[i]) (g[i][j]+=g[i+1][j-a[i]])%=10;        }    }    zero=E(0,0);    for(int i=1;i<=n;i++)    {        for(int j=0;j<N;j++) s1[j]=s2[j]=zero;        for(int j=0;j<=m;j++) s1[j]=E(f[i-1][j],0),s2[j]=E(g[i+1][j],0);        FFT(s1,1); FFT(s2,1);        for(int j=0;j<N;j++) s3[j]=s1[j]*s2[j];        FFT(s3,-1);        for(int j=1;j<=m;j++) printf("%d",((int)(s3[j].x+0.5))%10);        printf("\n");    }    return 0;}
0 0
原创粉丝点击