HDU 5307 He is Flying (生成函数+FFT)
题目大意:给你一个长度为$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)的更多相关文章
- FFT(快速傅里叶变换):HDU 5307 He is Flying
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8IAAAPeCAIAAABInTQaAAAgAElEQVR4nOy9fZReVXk3vP8ia+HqCy
- HDU 5307 He is Flying ——FFT
卷积的妙用,显然我们可以求出所有符合条件的右端点的和,然后减去左端点的和. 就是最后的答案.然后做一次前缀和,然后就变成了统计差是一个定值的情况. 令$A(s[i])++$ $B(s[i])+=i$ ...
- hdu 1402 A * B Problem Plus FFT
/* hdu 1402 A * B Problem Plus FFT 这是我的第二道FFT的题 第一题是完全照着别人的代码敲出来的,也不明白是什么意思 这个代码是在前一题的基础上改的 做完这个题,我才 ...
- loj6570 毛毛虫计数(生成函数FFT)
link 巨佬olinr的题解 <-- olinr很强 考虑生成函数 考虑直径上点数>=4的毛毛虫的直径,考虑直径中间那些节点以及他上面挂的那些点的EGF \(A(x)=\sum_{i\g ...
- 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 ...
- HDU 5515 Game of Flying Circus 二分
Game of Flying Circus Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem ...
- 挑选队友 (生成函数 + FFT + 分治)
链接:https://www.nowcoder.com/acm/contest/133/D来源:牛客网 题目描述 Applese打开了m个QQ群,向群友们发出了组队的邀请.作为网红选手,Applese ...
- 【BZOJ3771】Triple 生成函数 FFT 容斥原理
题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...
- HDU - 1402 A * B Problem Plus FFT裸题
http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$ 题解: 显然...用字符串模拟 ...
随机推荐
- 洛谷 P2412 查单词
P2412 查单词 题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个 ...
- 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 ...
- java.lang.NoClassDefFoundError: org/json/JSONException
问题: 解决办法:
- runtime objc_msgSend
runtime objc_msgSend 字数1781 阅读245 评论2 喜欢7 前言 想要通过runtime发送消息,就必须要掌握runtime如何发送消息,是调用哪个函数?又是如何调用的?本篇 ...
- adbd cannot run as root in production builds的解决方法
部分手机root后,使用adb root会出现这个提示. 原因是root不彻底. adb shell之后进入到$界面,su一下才进入到#. 这个之后可以使用root功能了. 注意到,这个时候exit的 ...
- Linux - 控制台界面,虚拟界面,字符界面
tty控制台终端. pts虚拟终端. tty1 图形界面. tty2 字符界面. Ctrl+Alt+F2-6 在字符界面下,通过Alt+F2 切换回来.或者切换到其他的字符界面. Alt+F2 pts ...
- struts的工作流程
- 一个请求过来,走前端控制器StrutsPrepareAndExecuteFilter -前端控制器是一个过滤器,过滤器中的核心方法是doFilter(),doFilter方法中首先处 ...
- Linux Oracle服务启动&停止脚本与开机自启动
在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设定相关参数,首先先介 ...
- SqlServer执行存储过程时,参数值为null,sql语句参数值变成default
从C#代码里传入参数到调用存储过程,参数的值为null,执行存储过程一直提示需要参数 '@xxx',但未提供该参数.通过profiler发现生成的参数值变成为default. 解决方案:1.将Para ...
- .net 对称加密
后台 public class CryptoHelper { // 对称加密算法提供器 private ICryptoTransform encryptor ...