bzoj 4332: JSOI2012 分零食 fft

    xiaoxiao2021-03-25  135

    题意

    MN01+2+32+3+1xf(x)=a2xx+a1x+a0mo M<=10000mo<=255N<=108a2<=4a1<=300a0<=100

    分析

    g[i,j]ji,f[i]i

    g[i,j]=j1k=1g[i1,jk]f[k]

    mi=1g[i,m]

    p[i,j]=ik=1g[k,j]

    p[i,j]=p[i2,j]+i2k=1g[i2+k,j]

    p[i,j]=p[i2,j]+i2k=1j1l=1g[k,l]g[i2,jl]

    p[i,j]=p[i2,j]+j1l=1i2k=1g[k,l]g[i2,jl]

    p[i,j]=p[i2,j]+j1l=1p[i2,l]g[i2,jl]

    O(mlogmlogn)

    代码

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<complex> #include<cmath> #define pi acos(-1) #define N 50005 #define LL long long using namespace std; typedef complex<double> com; int n,m,MOD,a1,a2,a3,f[N],rev[N],g[N],p[N],len,lg; com a[N],b[N]; void fft(com *a,int f) { for (int i=0;i<len;i++) if (i<rev[i]) swap(a[i],a[rev[i]]); for (int i=1;i<len;i<<=1) { com wn(cos(pi/i),f*sin(pi/i)); for (int j=0;j<len;j+=(i<<1)) { com w(1,0); for (int k=0;k<i;k++) { com u=a[j+k],v=w*a[j+k+i]; a[j+k]=u+v;a[j+k+i]=u-v; w*=wn; } } } if (f==-1) for (int i=0;i<len;i++) a[i]/=len; } void solve2() { for (int i=0;i<len;i++) a[i]=p[i],b[i]=g[i]; fft(a,1);fft(b,1); for (int i=0;i<len;i++) a[i]*=b[i]; fft(a,-1); for (int i=1;i<=m;i++) p[i]=(p[i]+(int)(a[i].real()+0.1))%MOD; for (int i=0;i<len;i++) a[i]=g[i]; fft(a,1); for (int i=0;i<len;i++) a[i]*=a[i]; fft(a,-1); for (int i=1;i<=m;i++) g[i]=((int)(a[i].real()+0.1))%MOD; } void solve1() { for (int i=0;i<len;i++) a[i]=f[i],b[i]=g[i]; fft(b,1);fft(a,1); for (int i=0;i<len;i++) a[i]*=b[i]; fft(a,-1); for (int i=1;i<=m;i++) g[i]=((int)(a[i].real()+0.1))%MOD,p[i]=(p[i]+g[i])%MOD; } int main() { scanf("%d%d%d%d%d%d",&m,&MOD,&n,&a1,&a2,&a3); for (int i=1;i<=m;i++) g[i]=p[i]=f[i]=((LL)a1*i%MOD*i%MOD+(LL)a2*i%MOD+a3)%MOD; for (len=1;len<=m*2;len<<=1,lg++); for (int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1)); int now=0,w=1; while (w*2<=n) w*=2,now++; while (now) { now--; solve2(); if (n&(1<<now)) solve1(); } printf("%d",p[m]); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-6752.html

    最新回复(0)