HDU5307 He is Flying
InputThe first line of the input is a single integer T (T=5)T (T=5), indicating the number of testcases.
For each testcase, the first line contains one integer nn. The second line contains nnnon-negative integers, which mean the length of every section. If we denote the total length of all the sections as ss, we can guarantee that 0≤s≤500000≤s≤50000 and 1≤n≤1000001≤n≤100000.
OutputFor each testcase, print s+1s+1 lines. The single number in the ii-th line indicates the total pleasure JRY can get if he races all the ways of length i−1i−1.
Sample Input
2 3 1 2 3 4 0 1 2 3
Sample Output
0 1 1 3 0 2 3 1 3 1 6 0 2 7
数学问题 生成函数 FFT
给一个数列,若有一个数对(i,j)满足sum[i]-sum[j-1]==S,则得到i-(j-1)的收益,求S取0到[数列总和]的每一个值时,各自的全部收益。
神一样的构造解……
看到数据范围这么大,又是求所有方案的累计贡献,普通的方法显然难以奏效。这时候就要考虑生成函数了。
如果把这看成一个多项式问题,两元相乘时次数相加,系数相乘,那么让题目中的"定值"在指数上体现出来。
↑ ΣS <=50000,那么让x^i这一位存储S=i时的收益,那么应该计算出所有的 [i-(j-1)]*x^s ,即为路程为s时的收益
那么就要构造能得到 [i-(j-1)]*x^s 形式的项的多项式。
根据sum[i]-sum[j-1]==S可以有:
Σ([ai]*x^sum[i])*Σ(x^-(sum[j-1]) - Σ(x^sum[i])*Σ([a(j-1)]x^-(sum[j-1])
这样算卷积,指数部分得到sum[i]-sum[j-1],系数部分得到所有的(i-(j-1)),岂不美哉。
S取0的情况可以特判O(n)处理
传说FFT会爆精度,用了Long double以后成功AC
然后试了试NTT取超大模数强行算,对拍过了一些小数据,然而交上去TLE了
↑看到别人的NTT是可以过的,那就是我写的有问题,然而懒得改了先放着
FFT:
/*by SilverN*/ #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define LL long long using namespace std; const long double pi=acos(-1.0); const int mxn=350021; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct com{ long double x,y; com operator + (const com b){return (com){x+b.x,y+b.y};} com operator - (const com b){return (com){x-b.x,y-b.y};} com operator * (const com b){return (com){x*b.x-y*b.y,x*b.y+y*b.x};} }a[mxn],b[mxn],c[mxn]; int N,l,rev[mxn]; void FFT(com *a,int flag){ int i,j,k; for(i=0;i<N;i++)if(rev[i]>i)swap(a[rev[i]],a[i]); for(i=1;i<N;i<<=1){ com wn=(com){cos(pi/i),flag*sin(pi/i)}; for(j=0;j<N;j+=(i<<1)){ com w=(com){1,0}; for(k=0;k<i;k++,w=w*wn){ com x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y; a[i+j+k]=x-y; } } } if(flag==-1)for(i=0;i<N;i++)a[i].x/=N; return; } int n,w[mxn]; LL ans[mxn]; int smm[mxn]; void init(){ n=read(); LL cnt=0; ans[0]=0; for(int i=1;i<=n;i++){ w[i]=read(); smm[i]=smm[i-1]+w[i]; if(!w[i]){//0 cnt++; ans[0]+=cnt*(cnt+1)/2; } else cnt=0; } return; } int main(){ int i,j; int T=read(); while(T--){ init(); // for(i=1;i<=n;i++)printf("%d ",smm[i]); // printf("\n"); memset(a,0,sizeof a); memset(b,0,sizeof b); memset(c,0,sizeof c); int ed=smm ; int m=ed<<1; for(N=1,l=0;N<=m;N<<=1)l++; for(i=0;i<N;i++){ rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); } // for(i=1;i<=n;i++){ a[smm[i]].x+=i; b[ed-smm[i-1]].x+=1; } /* for(i=0;i<=ed;i++)printf("%.2Lf ",a[i].x); printf("\n"); for(i=0;i<=ed;i++)printf("%.2Lf ",b[i].x); printf("\n"); */ FFT(a,1);FFT(b,1); for(i=0;i<=N;i++) c[i]=a[i]*b[i]; FFT(c,-1); memset(a,0,sizeof a); memset(b,0,sizeof b); for(i=1;i<=n;i++){ a[smm[i]].x+=1; b[ed-smm[i-1]].x+=i-1; } FFT(a,1);FFT(b,1); for(i=0;i<=N;i++){ a[i]=a[i]*b[i]; } FFT(a,-1); for(i=0;i<=N;i++)c[i]=c[i]-a[i]; printf("%lld\n",ans[0]); for(i=1;i<=ed;i++){ printf("%lld\n",(LL)(c[i+ed].x+0.5)); } } return 0; }
TLE的NTT
/*by SilverN*/ #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define LL long long using namespace std; //const LL P=(1LL<<47)*7*4451+1; const LL P=479*(1<<21)+1; //const LL mod=479*(1<<21)+1; const int mxn=130021; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } LL a[mxn],b[mxn],c[mxn]; int N,l; LL mul(LL x,LL y) { LL res=0; while(y){ if(y&1)res=(res+x)%P; x=(x<<1)%P; y>>=1; } return res; } LL ksm(LL a,LL k){ LL res=1; while(k){ if(k&1)res=mul(res,a); a=mul(a,a); k>>=1; } return res; } int rev[mxn]; void NTT(LL *a,int flag){ int i,j,k; for(i=0;i<N;i++)if(rev[i]>i)swap(a[rev[i]],a[i]); for(i=1;i<N;i<<=1){ LL gn=ksm(3,(P-1)/(i<<1)); int p=i<<1; for(j=0;j<N;j+=p){ LL g=1; for(k=0;k<i;k++,g=mul(g,gn)){ LL x=a[j+k],y=mul(g,a[j+k+i]); a[j+k]=(x+y)%P; a[i+j+k]=(x-y+P)%P; } } } if(flag==-1){ reverse(a+1,a+N); LL inv=ksm(N,P-2); for(i=0;i<N;i++)a[i]=mul(a[i],inv)%P; } return; } int n,w[mxn]; LL ans[mxn]; int smm[mxn]; void init(){ n=read(); LL cnt=0; ans[0]=0; for(int i=1;i<=n;i++){ w[i]=read(); smm[i]=smm[i-1]+w[i]; if(!w[i]){//0 cnt++; ans[0]+=cnt*(cnt+1)/2; } else cnt=0; } return; } int main(){ int i,j; int T=read(); while(T--){ init(); memset(a,0,sizeof a); memset(b,0,sizeof b); memset(c,0,sizeof c); int ed=smm ; int m=ed<<1; for(N=1,l=0;N<=m;N<<=1)l++; for(i=0;i<N;i++){ rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); } // for(i=1;i<=n;i++){ a[smm[i]]+=i; b[ed-smm[i-1]]+=1; } NTT(a,1);NTT(b,1); // for(i=0;i<=N;i++)printf("%lld ",a[i]);printf("\n"); for(i=0;i<=N;i++) c[i]=mul(a[i],b[i])%P; NTT(c,-1); memset(a,0,sizeof a); memset(b,0,sizeof b); for(i=1;i<=n;i++){ a[smm[i]]+=1; b[ed-smm[i-1]]+=i-1; } NTT(a,1);NTT(b,1); for(i=0;i<=N;i++){ a[i]=mul(a[i],b[i])%P; } NTT(a,-1); for(i=0;i<=N;i++)c[i]=(c[i]-a[i]+P)%P; printf("%lld\n",ans[0]); for(i=1;i<=ed;i++){ printf("%lld\n",c[i+ed]); } } return 0; }
- HDU5307 He is Flying
- hdu5307 He is Flying [cdq分治+FFT]
- hdu5307 He is Flying FFT
- [FFT] [HDU5307] He is Flying
- HDU5307 He is Flying(FFT)
- [hdu5307] He is Flying [FFT+数学推导]
- hdu 5307 He is Flying 2015 Multi-University Training Contest 2 快速傅里叶变换
- 【HDU】5307 He is Flying【分别统计+NTT】
- HDU 5307 He is Flying ——FFT
- hdu 5307 He is Flying
- HDU 5307 He is Flying 构造多项式+FFT
- hdu 5307 He is Flying [FFT]
- 多校第二场1008 He is flying
- HDU 5307 He is Flying【FFT】
- He is a walking dictionary
- sicily 1558 He is Offside!
- eclipse出现错误:he type java.util.Map$Entry cannot be resolved. It is indirectly referenced
- he file is absent or does not have execute permission
- he is finding this trip very exciting