HDU 5358 First One(枚举+尺举法)
来源:互联网 发布:武汉ui知乎 编辑:程序博客网 时间:2024/05/28 09:31
题目链接:传送门
题意:设f(i,j)表示区间[i,j]内元素的和 ,定义 SUM(i,j) = [log2(f(i,j))+1]*(i+j)
求 sigma(sum (i,j)) ( 1<=i<=n,i<=j<=n )
分析: log2(f(i,j))表示f(i,j)转换为2进制的长度,然后我们经过分析log2(f(i,j))+1的值域
为[1,34]然后我们枚举log2(f(i,j))+1的值,例如我们枚举其值为k,对于一个k我们找到所有满足
条件的区间(i,j),这个条件的代数表达为 2^(k-1)<= f(i,j) <=2^k-1;
因此我们需要再枚举一个区间的左端点,对于一个给定的左端点,因为f(i,j)在给定i的情况下单调,
我们可以用尺举发求得一个区间[l,r],使得区间内的j (l<=j<=r)都瞒住sum(i,j)+1=k;
然后区间(i+j)的和可以表示为 i*(r-l+1) + (r+l)*(r-l+1)/2;
代码如下:
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 1e5+10;typedef long long LL;LL sum[maxn];int main(){ int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); sum[0]=0; for(int i=1;i<=n;i++){ LL x; scanf("%I64d",&x); sum[i]=sum[i-1]+x; } LL ans = 0; for(LL k = 1;k<=34;k++){ LL l=1,r=0; LL lmax = 1LL<<(k-1),rmax=(1LL<<k)-1; if(k==1) lmax = 0; for(LL i=1;i<=n;i++){ l=max((LL)i,l); while(l<=n&&sum[l]-sum[i-1]<lmax) l++; r=max(l-1,r); while(r+1<=n&&sum[r+1]-sum[i-1]<=rmax&&sum[r+1]-sum[i-1]>=lmax)r++; if(l>r) continue; ans=ans+(i*(r-l+1)+(r+l)*(r-l+1)/2)*k; } } printf("%I64d\n",ans); } return 0;}
1 0
- 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
- 【瞎搞】 HDU 5358 First One
- hdu 5358 First One 数学
- hdu 5358 First One 2015多校联合训练赛#6 枚举
- HDU 5358 多校第6场 First One
- hdu 5358 First One(想法题)
- hdu 5358 First One(二进制+twopoint)
- hdu 5358 First One (尺取法)
- HDU 5358 First One(尺取法)
- HDU 5358 First One 数学+尺取法
- 数学题(First One,HDU 5358)
- java 7 collection 详解(一)
- CSU 1325: A very hard problem 莫比乌斯反演
- ios 读取大文件
- java 7 collection 详解(二)
- 对象排序 — java 7 collection详解(三)
- HDU 5358 First One(枚举+尺举法)
- zoj 1113 u Calculate e(小数点精度保留)
- linux下vim命令详解
- volley
- HDU 4686 Arc of Dream(矩阵快速幂)
- 网络超时设置connectionTimeout和SoTimeout的区别
- jsp+servlet+tomcat简单的数据库查询项目
- hdu2853Assignment kM算法
- Contest 5 1005 MZL's chemistry【打表= =】