hdu 5358 First One [枚举+尺取法]
来源:互联网 发布:it was not until 编辑:程序博客网 时间:2024/05/18 01:00
题意:给你n个数,求他给出的求和式
题解:由于求和式中含有log2,当我们枚举左端点的时候,右端点在一定范围内log2值是不会变的,所以我们可以对每一种log2的取值做枚举,然后枚举每一个左端点,再找到右端点符合条件的范围,但是假如用二分查找右端点得到结果时间复杂度n*logsum*logn,TLE,所以可以考虑用尺取法,所以总的复杂度为n*logn。
AC代码:
#include<stdio.h>#include<math.h>typedef long long ll;ll a[100005],sum[100005];ll cf2[40]; void init() { ll k = 1; for(int i=0; i<=34; ++i) { cf2[i] = (k<<(i)); } } int main(){init();ll T;scanf("%lld",&T);while(T--){ll n;scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];}sum[n+1]=(ll)1E17;ll ans=0,gg;for(int i=1;i<=n;++i){ int p=i; while(sum[p]==sum[i-1]&&p<=n+1)++p; --p; if(p>=i)ans+=(ll)(i*3+p)*(ll)(p-i+1)/2; }ll now=1;ll last=0;for(int j=0;j<=33;j++){ int p1=0,p2=0;for(int i=1; i<=n; ++i){ ll adc = sum[i-1] + cf2[j]; while(sum[p1]<adc && p1<=n)++p1; adc = sum[i-1] +cf2[j+1]; while(sum[p2]<adc && p2<=n+1)++p2;--p2; if(p2>=p1&&p2)ans+=(j+1)*(ll)(i*2+p1+p2)*(ll)(p2-p1+1)/2;}}printf("%lld\n",ans);}return 0;}
阅读全文
0 0
- hdu 5358 First One [枚举+尺取法]
- hdu 5358 First One (尺取法)
- HDU 5358 First One(尺取法)
- HDU 5358 First One 数学+尺取法
- HDU 5338. First One(尺取法)
- hdu 5358 First One (2015多校第六场第6题)尺取法枚举区间和
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举+尺举法)
- HDU 5358 · First One【尺取法】【读题】【多校联赛】
- 多校第六场 1006 hdu 5358 First One(枚举)
- HDU 5358 First One
- HDU 5358 First One
- HDU 5358 First One
- hdu5358 First One 尺取法 多校联合第六场
- 【瞎搞】 HDU 5358 First One
- hdu 5358 First One 数学
- hdu 5358 First One 2015多校联合训练赛#6 枚举
- rails redis+sidekiq 异步执行作业任务
- struts2 类型转换
- NYOJ 448 寻找最大数
- java abstract意义:
- Ubuntu16.04开机死循环
- hdu 5358 First One [枚举+尺取法]
- crontab笔记整理
- POJ
- for循环数组冒泡排序
- AB1601读触摸芯片ASC0106的IIC波形图
- php——记中文验证码
- 机器学习实战--KNN算法
- zTree模糊搜索
- react webpack打包后怎么调试