题目传送门

题目大意:给你一个长度为$n$的自然数序列$a$,定义一段区间的权值为这一段区间里所有数的和,分别输出权值为$[0,\sum a_{i}]$的区间的长度之和

想到了生成函数的话,这道题并不难做。但很多细节真是不太好搞

我们首先预处理出前缀和s,那么一段区间$[l,r]$的权值就是$s_{r}-s_{l-1}$

容易联想到卷积

第一个多项式是 区间右端点的前缀和 作为指数的生成函数,每一项的系数是 右端点的编号之和

第二个多项式是 区间左端点的前缀和 作为指数的生成函数,每一项的系数是 左端点的编号之和

然而区间长度是相减而不是相乘

我们可以把问题转化成 右端点编号$*1$-左端点编号$*1$,求两次卷积再相减即可

然而左端点的前缀和是负数,我们把生成函数整体右移

然而序列里还有$0$的情况

如果序列里出现了连续的$0$,我们发现这部分答案我们无法通过卷积统计

因为按照我们的方法,在多项式对应的相同的位置卷积的话,两次统计的答案就被减掉了

所以连续的$0$对答案的影响通过$O(n)$扫一遍统计

每新加入一个新的$0$,就会多产生一个等差数列的贡献

另外答案比较大,$FFT$需要开$long\;double$

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 (1<<18)
#define M1 (N1<<1)
#define il inline
#define dd double
#define ld long double
#define ll long long
using namespace std; int T,n; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} const ld pi=acos(-);
struct cp{
ld x,y;
friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; }
friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; }
friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; }
}a[N1],b[N1],c[N1];
int r[N1];
void FFT(cp *s,int len,int type)
{
int i,j,k; cp wn,w,t;
for(i=;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]);
for(k=;k<=len;k<<=)
{
wn=(cp){cos(pi*2.0*type/k),sin(pi*2.0*type/k)};
for(i=;i<len;i+=k)
{
w=(cp){,};
for(j=;j<(k>>);j++,w=w*wn)
{
t=w*s[i+j+(k>>)];
s[i+j+(k>>)]=s[i+j]-t;
s[i+j]=s[i+j]+t;
}
}
}
}
void FFT_Main(int len)
{
FFT(a,len,); FFT(b,len,);
for(int i=;i<len;i++) c[i]=a[i]*b[i];
FFT(c,len,-);
for(int i=;i<len;i++) c[i].x/=len;
} int v[N1],s[N1];
ll ans[N1]; int main()
{
scanf("%d",&T);
while(T--) { memset(v,,sizeof(v)); memset(s,,sizeof(s)); memset(r,,sizeof(r)); memset(ans,,sizeof(ans));
int i,j,maxn=,len,L,num;
scanf("%d",&n);
for(i=;i<=n;i++) v[i]=gint(), s[i]=s[i-]+v[i], maxn=max(maxn,s[i]);
if(!maxn)
{
for(i=;i<=n;i++)
ans[]+=1ll*(i+)*i/;
printf("%lld\n",ans[]);
continue;
} for(len=,L=;len<maxn+maxn+;len<<=,L++);
for(i=;i<len;i++) r[i]=(r[i>>]>>)|((i&)<<(L-)); memset(a,,sizeof(a)); memset(b,,sizeof(b));
for(i=;i<=n;i++) a[s[i]].x+=i;
for(i=;i<=n;i++) b[-s[i]+maxn].x++;
FFT_Main(len);
for(i=maxn;i<=(maxn<<);i++) ans[i-maxn]=(ll)(c[i].x+0.5); memset(a,,sizeof(a)); memset(b,,sizeof(b));
for(i=;i<=n;i++) a[s[i]].x++;
for(i=;i<=n;i++) b[-s[i]+maxn].x+=i;
FFT_Main(len);
for(i=maxn;i<=(maxn<<);i++) ans[i-maxn]-=(ll)(c[i].x+0.5); for(i=,num=;i<=n;i++)
if(!v[i]){ num++; ans[]+=1ll*(num+)*(num)/2ll; }
else{ num=; }
for(i=;i<=maxn;i++) printf("%lld\n",ans[i]);
//puts("");
}
return ; }

HDU 5307 He is Flying (生成函数+FFT)的更多相关文章

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

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8IAAAPeCAIAAABInTQaAAAgAElEQVR4nOy9fZReVXk3vP8ia+HqCy

  2. HDU 5307 He is Flying ——FFT

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

  3. hdu 1402 A * B Problem Plus FFT

    /* hdu 1402 A * B Problem Plus FFT 这是我的第二道FFT的题 第一题是完全照着别人的代码敲出来的,也不明白是什么意思 这个代码是在前一题的基础上改的 做完这个题,我才 ...

  4. loj6570 毛毛虫计数(生成函数FFT)

    link 巨佬olinr的题解 <-- olinr很强 考虑生成函数 考虑直径上点数>=4的毛毛虫的直径,考虑直径中间那些节点以及他上面挂的那些点的EGF \(A(x)=\sum_{i\g ...

  5. 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 ...

  6. HDU 5515 Game of Flying Circus 二分

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

  7. 挑选队友 (生成函数 + FFT + 分治)

    链接:https://www.nowcoder.com/acm/contest/133/D来源:牛客网 题目描述 Applese打开了m个QQ群,向群友们发出了组队的邀请.作为网红选手,Applese ...

  8. 【BZOJ3771】Triple 生成函数 FFT 容斥原理

    题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...

  9. HDU - 1402 A * B Problem Plus FFT裸题

    http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$ 题解: 显然...用字符串模拟 ...

随机推荐

  1. Tomcat日志配置远程Syslog采集

    http://blog.csdn.net/leizi191110211/article/details/51593748

  2. SSL延迟

    原文链接 据说,Netscape公司当年设计SSL协议的时候,有人提过,将互联网所有链接都变成HTTPs开头的加密链接. 这个建议没有得到采纳,原因之一是HTTPs链接比不加密的HTTP链接慢很多.( ...

  3. centos 解压压缩包到指定目录

    解压.tar.gz文件: tar -zxvf web.tar.gz tar不支付解压文件到指定的目录! 解压.war .zip文件到指定目录: unzip web.war -d webapps/ROO ...

  4. Android中加入水平线和垂直线

    1.加入水平线 <View android:layout_height="0.5dip" android:background="#686868" and ...

  5. iOS音频播放之AudioQueue(一):播放本地音乐

    AudioQueue简单介绍 AudioStreamer说明 AudioQueue具体解释 AudioQueue工作原理 AudioQueue主要接口 AudioQueueNewOutput Audi ...

  6. DexClassLoader和PathClassLoader类载入机制

    0x00 在DexClassLoader和PathClassLoader载入Dex流程一文中,我们分析了dex文件怎样形成了DexFile结构体.本文中解说类载入机制,实际上就是生成ClassObje ...

  7. python 读取二进制文件 转为16进制输出

    示例: #!/usr/bin/env python #encoding: utf-8 import binascii fh = open(r'C:\Temp\img\2012517165556.png ...

  8. CNN中的局部连接(Sparse Connectivity)和权值共享

    局部连接与权值共享 下图是一个很经典的图示,左边是全连接,右边是局部连接. 对于一个1000 × 1000的输入图像而言,如果下一个隐藏层的神经元数目为10^6个,采用全连接则有1000 × 1000 ...

  9. LDA解决的问题

    人类是怎么生成文档的呢?LDA的这三位作者在原始论文中给了一个简单的例子.比如假设事先给定了这几个主题:Arts.Budgets.Children.Education,然后通过学习训练,获取每个主题T ...

  10. POJ3414 Pots

    题目: 给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作 FILL(i)        将第i个容器从水龙头里装满(1 ≤ i ≤ 2); DROP(i)        将第i个容器抽干 ...