JRY wants to drag racing along a long road. There are 0.

InputThe first line of the input is a single integer i−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:

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #define LL long long
  8 using namespace std;
  9 const long double pi=acos(-1.0);
 10 const int mxn=350021;
 11 int read(){
 12     int x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return x*f;
 16 }
 17 struct com{
 18     long double x,y;
 19     com operator + (const com b){return (com){x+b.x,y+b.y};}
 20     com operator - (const com b){return (com){x-b.x,y-b.y};}
 21     com operator * (const com b){return (com){x*b.x-y*b.y,x*b.y+y*b.x};}
 22 }a[mxn],b[mxn],c[mxn];
 23 int N,l,rev[mxn];
 24 void FFT(com *a,int flag){
 25     int i,j,k;
 26     for(i=0;i<N;i++)if(rev[i]>i)swap(a[rev[i]],a[i]);
 27     for(i=1;i<N;i<<=1){
 28         com wn=(com){cos(pi/i),flag*sin(pi/i)};
 29         for(j=0;j<N;j+=(i<<1)){
 30             com w=(com){1,0};
 31             for(k=0;k<i;k++,w=w*wn){
 32                 com x=a[j+k],y=w*a[j+k+i];
 33                 a[j+k]=x+y;
 34                 a[i+j+k]=x-y;
 35             }
 36         }
 37     }
 38     if(flag==-1)for(i=0;i<N;i++)a[i].x/=N;
 39     return;
 40 }
 41 int n,w[mxn];
 42 LL ans[mxn];
 43 int smm[mxn];
 44 void init(){
 45     n=read();
 46     LL cnt=0;
 47     ans[0]=0;
 48     for(int i=1;i<=n;i++){
 49         w[i]=read();
 50         smm[i]=smm[i-1]+w[i];
 51         if(!w[i]){//0
 52             cnt++;
 53             ans[0]+=cnt*(cnt+1)/2;
 54         }
 55         else cnt=0;
 56     }
 57     return;
 58 }
 59 int main(){
 60     int i,j;
 61     int T=read();
 62     
 63     while(T--){
 64         init();
 65 //        for(i=1;i<=n;i++)printf("%d ",smm[i]);
 66 //        printf("\n");
 67         memset(a,0,sizeof a);
 68         memset(b,0,sizeof b);
 69         memset(c,0,sizeof c);
 70         int ed=smm[n];
 71         int m=ed<<1;
 72         for(N=1,l=0;N<=m;N<<=1)l++;
 73         for(i=0;i<N;i++){
 74             rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
 75         }
 76         //
 77         for(i=1;i<=n;i++){
 78             a[smm[i]].x+=i;
 79             b[ed-smm[i-1]].x+=1;
 80         }
 81         /*
 82         for(i=0;i<=ed;i++)printf("%.2Lf ",a[i].x);
 83         printf("\n");
 84         for(i=0;i<=ed;i++)printf("%.2Lf ",b[i].x);
 85         printf("\n");
 86         */
 87         FFT(a,1);FFT(b,1);
 88         for(i=0;i<=N;i++)
 89             c[i]=a[i]*b[i];
 90         FFT(c,-1);
 91         memset(a,0,sizeof a);
 92         memset(b,0,sizeof b);
 93         for(i=1;i<=n;i++){
 94             a[smm[i]].x+=1;
 95             b[ed-smm[i-1]].x+=i-1;
 96         }
 97         FFT(a,1);FFT(b,1);
 98         for(i=0;i<=N;i++){
 99             a[i]=a[i]*b[i];
100         }
101         FFT(a,-1);
102         for(i=0;i<=N;i++)c[i]=c[i]-a[i];
103         printf("%lld\n",ans[0]);
104         for(i=1;i<=ed;i++){
105             printf("%lld\n",(LL)(c[i+ed].x+0.5));
106         }
107     }
108     return 0;
109 }

 

TLE的NTT

 

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #define LL long long
  8 using namespace std;
  9 //const LL P=(1LL<<47)*7*4451+1;
 10 const LL P=479*(1<<21)+1;
 11 //const LL mod=479*(1<<21)+1;
 12 const int mxn=130021;
 13 int read(){
 14     int x=0,f=1;char ch=getchar();
 15     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 16     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 17     return x*f;
 18 }
 19 LL a[mxn],b[mxn],c[mxn];
 20 int N,l;
 21 LL mul(LL x,LL y) {
 22     LL res=0;
 23     while(y){
 24         if(y&1)res=(res+x)%P;
 25         x=(x<<1)%P;
 26         y>>=1;
 27     }
 28     return res;
 29 }
 30 LL ksm(LL a,LL k){
 31     LL res=1;
 32     while(k){
 33         if(k&1)res=mul(res,a);
 34         a=mul(a,a);
 35         k>>=1;
 36     }
 37     return res;
 38 }
 39 int rev[mxn];
 40 void NTT(LL *a,int flag){
 41     int i,j,k;
 42     for(i=0;i<N;i++)if(rev[i]>i)swap(a[rev[i]],a[i]);
 43     for(i=1;i<N;i<<=1){
 44         LL gn=ksm(3,(P-1)/(i<<1));
 45         int p=i<<1;
 46         for(j=0;j<N;j+=p){
 47             LL g=1;
 48             for(k=0;k<i;k++,g=mul(g,gn)){
 49                 LL x=a[j+k],y=mul(g,a[j+k+i]);
 50                 a[j+k]=(x+y)%P;
 51                 a[i+j+k]=(x-y+P)%P;
 52             }
 53         }
 54     }
 55     if(flag==-1){
 56         reverse(a+1,a+N);
 57         LL inv=ksm(N,P-2);
 58         for(i=0;i<N;i++)a[i]=mul(a[i],inv)%P;
 59     }
 60     return;
 61 }
 62 int n,w[mxn];
 63 LL ans[mxn];
 64 int smm[mxn];
 65 void init(){
 66     n=read();
 67     LL cnt=0;
 68     ans[0]=0;
 69     for(int i=1;i<=n;i++){
 70         w[i]=read();
 71         smm[i]=smm[i-1]+w[i];
 72         if(!w[i]){//0
 73             cnt++;
 74             ans[0]+=cnt*(cnt+1)/2;
 75         }
 76         else cnt=0;
 77     }
 78     return;
 79 }
 80 int main(){
 81     int i,j;
 82     int T=read();
 83     while(T--){
 84         init();
 85         memset(a,0,sizeof a);
 86         memset(b,0,sizeof b);
 87         memset(c,0,sizeof c);
 88         int ed=smm[n];
 89         int m=ed<<1;
 90         for(N=1,l=0;N<=m;N<<=1)l++;
 91         for(i=0;i<N;i++){
 92             rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
 93         }
 94         //
 95         for(i=1;i<=n;i++){
 96             a[smm[i]]+=i;
 97             b[ed-smm[i-1]]+=1;
 98         }
 99         
100         NTT(a,1);NTT(b,1);
101 //        for(i=0;i<=N;i++)printf("%lld ",a[i]);printf("\n");
102         for(i=0;i<=N;i++)
103             c[i]=mul(a[i],b[i])%P;
104         NTT(c,-1);
105         memset(a,0,sizeof a);
106         memset(b,0,sizeof b);
107         for(i=1;i<=n;i++){
108             a[smm[i]]+=1;
109             b[ed-smm[i-1]]+=i-1;
110         }
111         NTT(a,1);NTT(b,1);
112         for(i=0;i<=N;i++){
113             a[i]=mul(a[i],b[i])%P;
114         }
115         NTT(a,-1);
116         for(i=0;i<=N;i++)c[i]=(c[i]-a[i]+P)%P;
117         printf("%lld\n",ans[0]);
118         for(i=1;i<=ed;i++){
119             printf("%lld\n",c[i+ed]);
120         }
121     }
122     return 0;
123 }

 

相关文章: