题目传送门

题目大意:给你一个长度为$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. 洛谷 P2412 查单词

    P2412 查单词 题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个 ...

  2. Maven错误:[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?的解决方法

    错误: [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather tha ...

  3. java.lang.NoClassDefFoundError: org/json/JSONException

    问题: 解决办法:

  4. runtime objc_msgSend

    runtime objc_msgSend 字数1781 阅读245 评论2 喜欢7  前言 想要通过runtime发送消息,就必须要掌握runtime如何发送消息,是调用哪个函数?又是如何调用的?本篇 ...

  5. adbd cannot run as root in production builds的解决方法

    部分手机root后,使用adb root会出现这个提示. 原因是root不彻底. adb shell之后进入到$界面,su一下才进入到#. 这个之后可以使用root功能了. 注意到,这个时候exit的 ...

  6. Linux - 控制台界面,虚拟界面,字符界面

    tty控制台终端. pts虚拟终端. tty1 图形界面. tty2 字符界面. Ctrl+Alt+F2-6 在字符界面下,通过Alt+F2 切换回来.或者切换到其他的字符界面. Alt+F2 pts ...

  7. struts的工作流程

    - 一个请求过来,走前端控制器StrutsPrepareAndExecuteFilter        -前端控制器是一个过滤器,过滤器中的核心方法是doFilter(),doFilter方法中首先处 ...

  8. Linux&nbsp;Oracle服务启动&amp;停止脚本与开机自启动

    在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设定相关参数,首先先介 ...

  9. SqlServer执行存储过程时,参数值为null,sql语句参数值变成default

    从C#代码里传入参数到调用存储过程,参数的值为null,执行存储过程一直提示需要参数 '@xxx',但未提供该参数.通过profiler发现生成的参数值变成为default. 解决方案:1.将Para ...

  10. .net 对称加密

    后台   public class CryptoHelper     {         // 对称加密算法提供器         private ICryptoTransform encryptor ...