Problem Description
JRY wants to drag racing along a long road. There are n sections on the road, the i -th section has a non-negative integer length si .
JRY will choose some continuous sections to race (at an unbelievable speed), so there are totally n(n+1)2 different ways for him to ride.
If JRY rides across from the i -th section to the j -th section, he would gain j?i+1 pleasure. Now JRY wants to know, if he tries all the ways whose length is s ,
what's the total pleasure he can get. Please be aware that in the problem, the length of one section could be zero, which means that the length is so trivial that we can regard it as 0
Input
The first line of the input is a single integer T (T=5) , indicating the number of testcases.

For each testcase, the first line contains one integer n . The second line contains n non-negative integers,
which mean the length of every section. If we denote the total length of all the sections as s , we can guarantee that 0≤s≤50000 and 1≤n≤100000 .
Output
For each testcase, print s+1 lines. The single number in the i -th line indicates the total pleasure JRY can get if he races all the ways of length 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

解题思路:
首先可以得到一个暴力的做法,就是枚举每一段的起点终点将答案计入数组,
输出就好了,时间复杂度$O(n^3)$,前缀和优化就是$O(n^2)$。
分析上述算法,发现如果固定住答案数组的一位(假设现在就是在求第$x$项的答案,设前$i$项$s[]$的前缀和为$sum[i]$)
那么上述算法可以表述为:
$Ans(x)=\sum\limits_{i=1}^{n}\sum\limits_{j=i}^{n}[sum[j]-sum[i-1]==x](j-i+1)$
由于$sum[j]-sum[i-1]$为固定的,可以认为这是在暗示这题正解是求生成函数第$x$项系数。
那我们就往生成函数上想吧。
那么由于后面是$j-i+1$是加减法关系,由于次数不同,可以认为是两个生成函数分别与全是1的多项式乘积后的累和。
那么考虑是哪两个结果相加。这个好像只能是$j$和$i-1$了吧(指数形式提醒我们)。
设答案的生成函数多项式为$F(x)=f(0)+f(1)x+f(2)x^2+...$
设左右两部分贡献分别为$G$和$H$。(左边是根据$j$列出的多项式,右边是根据$i-1$列出的多项式)
那么
$F=G-H$
由于需要将多项式次数调平,所以:
$G=\sum\limits_{i=1}^{n}(i*x^{sum[i]})\sum\limits_{i=1}^{n}(x^{-sum[i-1]})$
同理:
$H=\sum\limits_{i=1}^{n}((i-1)x^{-sum[i-1]})\sum\limits_{i=1}^{n}x^{sum[i]}$
负数次幂加个大数最后减掉就好了。
注意这个式子并不能处理(i==0)的情况,因为$sum[-1]$并没有被定义。
分类讨论好麻烦,所以直接$O(n)$统计(i==0)的答案即可。
注意一定要写using namespace std;
代码:
 #include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int DLT=;
const long double PI=acos(-1.0);
struct cp{
long double x,y;
cp(){}
cp(long double a,long double b){x=a;y=b;}
cp friend operator + (cp a,cp b){return cp(a.x+b.x,a.y+b.y);}
cp friend operator - (cp a,cp b){return cp(a.x-b.x,a.y-b.y);}
cp friend operator * (cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
}A[],B[],C[],D[];
int T;
int n,m;
int lim;
int len;
int s[];
int pos[];
int sum[];
void init(void)
{
memset(A,,sizeof(A));
memset(B,,sizeof(B));
memset(C,,sizeof(C));
memset(D,,sizeof(D));
return ;
}
void FFT(cp *a,double flag)
{
for(int i=;i<len;i++)if(i<pos[i])std::swap(a[i],a[pos[i]]);
for(int i=;i<=len;i<<=)
{
cp wn(cos(2.00*flag*PI/i),sin(2.00*flag*PI/i));
for(int j=;j<len;j+=i)
{
cp w(,),t;
for(int k=;k<(i>>);k++,w=w*wn)
{
t=a[j+k+(i>>)]*w;
a[j+k+(i>>)]=a[j+k]-t;
a[j+k]=a[j+k]+t;
}
}
}
return ;
}
void work(void)
{
init();
long long a0();
int cnt();
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&s[i]);
if(!s[i])
{
cnt++;
a0+=1ll*cnt*(cnt+)/;
}else cnt=;
sum[i]=sum[i-]+s[i];
}
printf("%lld\n",a0);
while((<<lim)<(DLT<<))lim++;len=<<lim;
for(int i=;i<len;i++)pos[i]=(pos[i>>]>>)|((i&)<<(lim-));
for(int i=;i<=n;i++)
{
A[sum[i]].x+=i;B[DLT-sum[i-]].x+=;
C[sum[i]].x+=;D[DLT-sum[i-]].x+=i-;
}
FFT(A,),FFT(B,),FFT(C,),FFT(D,);
for(int i=;i<len;i++)A[i]=A[i]*B[i]-C[i]*D[i];
FFT(A,-);
for(int i=;i<=sum[n];i++)printf("%I64d\n",(long long)(A[i+DLT].x/len+0.2));
return ;
}
int main()
{
scanf("%d",&T);
while(T --> )work();
return ;
}

HDU-5307 He is Flying (FFT)的更多相关文章

  1. HDU 5307 He is Flying ——FFT

    卷积的妙用,显然我们可以求出所有符合条件的右端点的和,然后减去左端点的和. 就是最后的答案.然后做一次前缀和,然后就变成了统计差是一个定值的情况. 令$A(s[i])++$ $B(s[i])+=i$ ...

  2. FFT(快速傅里叶变换):HDU 5307 He is Flying

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8IAAAPeCAIAAABInTQaAAAgAElEQVR4nOy9fZReVXk3vP8ia+HqCy

  3. HDU 5307 He is Flying (生成函数+FFT)

    题目传送门 题目大意:给你一个长度为$n$的自然数序列$a$,定义一段区间的权值为这一段区间里所有数的和,分别输出权值为$[0,\sum a_{i}]$的区间的长度之和 想到了生成函数的话,这道题并不 ...

  4. HDU - 5307 :He is Flying (分治+FFT)(非正解)

    JRY wants to drag racing along a long road. There are nn sections on the road, the ii-th section has ...

  5. HDU 5515 Game of Flying Circus 二分

    Game of Flying Circus Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem ...

  6. HDU 5763 Another Meaning(FFT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5763 [题目大意] 给出两个串S和T,可以将S串中出现的T替换为*,问S串有几种表达方式. [题解 ...

  7. hdu 4656 Evaluation [任意模数fft trick]

    hdu 4656 Evaluation 题意:给出\(n,b,c,d,f(x) = \sum_{i=1}^{n-1} a_ix^i\),求\(f(b\cdot c^{2k}+d):0\le k < ...

  8. hdu 5730 Shell Necklace [分治fft | 多项式求逆]

    hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...

  9. hdu 5730 Shell Necklace —— 分治FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5730 DP式:\( f[i] = \sum\limits_{j=1}^{i} f[i-j] * a[j] ...

  10. hdu 4609 3-idiots(快速傅里叶FFT)

    比较裸的FFT(快速傅里叶变换),也是为了这道题而去学的,厚的白书上有简单提到,不过还是推荐看算法导论,讲的很详细. 代码的话是照着别人敲的,推荐:http://www.cnblogs.com/kua ...

随机推荐

  1. Redis介绍以及安装具体解释

    redis是一个key-value存储系统. 和Memcached类似.它支持存储的value类型相对很多其它,包含string(字符串).list(链表).set(集合).zset(sorted s ...

  2. max带来的冲突

    题目要求: /* * Copyright (c) 2014, 烟台大学计算机学院 * All rights reserved. * 文件名:sum123.cpp * 作 者:林海云 * 完毕日期:20 ...

  3. TCP/IP、UDP、 Http、Socket的差别

    网络由上往下分为: 表示层和应用层 :HTTP协议(基于传输层的TCP协议,主要解决怎样包装数据) 会话层 传输层: TCP协议(基于网络层的IP协议).TPC/IP协议(主要解决数据怎样在网络中传输 ...

  4. Linux 6.3下安装Oracle Enterprise Cloud Control 12c

    Oracle enterprise cloud control 12c的安装是一个比較复杂的过程,由于他须要依赖于Oracel database以及Oracle Weblogic. 如今Oracle已 ...

  5. input range 模拟滑块

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  6. hdu_3308 区间合并

    一两个月没写代码的确是手生的厉害,debug的好艰辛,,不过看到accept时的那种满足感真的就是爽 #include<iostream> #include<cstdio> # ...

  7. 安卓开发--scrollview

    package com.cnn.scrollviewdemo01; import android.R.integer; import android.annotation.SuppressLint; ...

  8. Java类和对象8

    按要求编写Java应用程序. (1)创建一个叫做People的类: 属性:姓名.年龄.性别.身高         行为:说话.计算加法.改名 编写能为所有属性赋值的构造方法: (2)创建主类: 创建一 ...

  9. ES6中常用的简写方式

    1. var foo = 'bar'; var baz = {foo}; baz // {foo: "bar"} // 等同于 var baz = {foo: foo}; 2. f ...

  10. vue子组件使用指令 同时绑定v-model 指令没有作用

    //这里直接上代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...