First One

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 690    Accepted Submission(s): 205

Problem Description
soda has an integer array a1,a2,…,an.
Let S(i,j) be
the sum of ai,ai+1,…,aj.
Now soda wants to know the value below:

∑i=1n∑j=in(⌊log2S(i,j)⌋+1)×(i+j)

Note: In this problem, you can consider log20 as
0.

 
Input
There are multiple test cases. The first line of input contains an integer T,
indicating the number of test cases. For each test case:



The first line contains an integer n (1≤n≤105),
the number of integers in the array.

The next line contains n integers a1,a2,…,an (0≤ai≤105).
 
Output
For each test case, output the value.
 
Sample Input
1
2
1 1
 
Sample Output
12
 
Source
 

题目大意:对题目中的式子求结果。

解题思路:由于0<=ai<=10^5,0<n<=10^5,所以0<=S(i,j)<10^12<2^34,设k=⌊log2S(i,j)⌋+1则1<=k<=34,那么我们

每次枚举k时,求解出全部符合条件的(i+j),求和就可以。

而对于每个k,求解(i+j)时。先预处理出s[i](s[i]=a1+……+ai。则sum(i,j)=s[j]-s[i-1]),那么接下来仅仅需找到全部

满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j)就可以。

对于求(i+j),我们再次枚举i,对每个i。求解出j的一个区间[l,r],使得对当前的i,有当l<=j<=r时,2^(k-1)

<=sum(i,j)<=2^k-1成立。那么对于当前的k,i,满足条件的i。j区间为[i,j](l<=j<=r)。这些区间相应同一个k和同一个i,这些区间的(i+j)的总和为:i*(r-l+1)+(r+l)*(r-l+1)/2。

枚举全然部的k和i,将全部和累加。

对于求解区间[l,r],如果k=a,在枚举i=b时,得到j的区间[L1,R1],那么同样的k,在枚举i=b+1时,得到j的区间[L2,R2]

一定不在区间[L1,R1]的左边,简单的说就是L2>L1。R2>R1。

因此查找l。r时能够降低范围。

代码例如以下:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-6)
#define inf (1<<28)
#define sqr(x) (x) * (x)
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef unsigned long long ULL; ll fl[35]={0,0,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592};
ll fr[35]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215,33554431,67108863,134217727,268435455,536870911,1073741823,2147483647,4294967295,8589934591,17179869183};
ll s[100005];
int main()
{
ll i,j,k,n,a,l,r,t;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d",&n);
for(i=1;i<=n;i++)
{
scanf("%I64d",&a);
s[i]=s[i-1]+a;
}
ll ans=0;
for(k=1;k<=34;k++)
{
l=1;
r=0; //移位操作控制sum(i,j)的范围。也能够用数组
//fl= k==1? 0:(1ll<<(k-1));fr=(1ll<<k)-1;
for(i=1;i<=n;i++)
{
l=max(i,l);
while(l<=n&&s[l]-s[i-1]<fl[k])//while(l<=n&&s[l]-s[i-1]<fl)
l++;
r=max(l-1,r);
while(r+1<=n&&s[r+1]-s[i-1]>=fl[k]&&s[r+1]-s[i-1]<=fr[k])//while(r+1<=n&&s[r+1]-s[i-1]>=fl[k]&&s[r+1]-s[i-1]<=fr)
r++;
if(l<=r)
ans+=(i*(r-l+1)+(r+l)*(r-l+1)/2)*k;
//ans+=(i+l+i+r)*(r-l+1)/2*k;
}
}
printf("%I64d\n",ans);
}
return 0;
}

HDU 5358 First One(枚举)的更多相关文章

  1. 2015多校第6场 HDU 5358 First One 枚举,双指针

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5358 题意:如题. 解法:观察式子发现,由于log函数的存在,使得这个函数的值域<=34,然后我 ...

  2. HDU 5358 尺取法+枚举

    题意:给一个数列,按如下公式求和. 分析:场上做的时候,傻傻以为是线段树,也没想出题者为啥出log2,就是S(i,j) 的二进制表示的位数.只能说我做题依旧太死板,让求和就按规矩求和,多考虑一下就能发 ...

  3. HDU 5358 First One(枚举)

    这道题假设依照表达式一个个来算肯定超时,下午时候想了一个O(nlogn*logn)的算法.可是t了.由于这道题卡的很紧几百个例子,必须nlogn的算法才干够ac 回到这道题,考虑log(sum(i,j ...

  4. Hdu 5358 First One (尺取法+枚举)

    题目链接: Hdu 5358 First One 题目描述: 数组a有n个元素,S[i,j]定义为a[i]+a[i+1]+.....+a[j],问:这个死东西等于多少? 解题思路: 二分肯定超,这个题 ...

  5. hdu 5358 First One

    题目链接:hdu 5358 思路不难理解,就是个尺取法而已,floor(log2X) + 1 就是求 X 的二进制表示的位数,对于题目来说这个值最多只是 30+,从这里入手开始枚举,运用尺取法可以达到 ...

  6. HDU 5358 多校第6场 First One

    First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tota ...

  7. HDU 5358(2015多校联合训练赛第六场1006) First One (区间合并+常数优化)

    pid=5358">HDU 5358 题意: 求∑​i=1​n​​∑​j=i​n​​(⌊log​2​​S(i,j)⌋+1)∗(i+j). 思路: S(i,j) < 10^10 & ...

  8. hdu 5358 First One 2015多校联合训练赛#6 枚举

    First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tota ...

  9. HDU 5778 abs (枚举)

    abs 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5778 Description Given a number x, ask positive ...

随机推荐

  1. lua 中string字符串的使用(string.len, string.char)

    table.keys 返回指定表格中的全部键. 格式: keys = table.keys(表格对象) 使用方法演示样例: local t = {a = 1, b = 2, c = 3} local ...

  2. 一个关于 UIPickerView 的 bug

    首先,我下描写叙述一下bug的发生情况: 在使用UIPickerView实现选择城市的时候.出现这样一个Bug 1.在iOS 6的系统上 2.Picker的数据上省份一栏选择了"香港&quo ...

  3. Autodesk 举办的 Revit 2015 二次开发速成( 1.5 天),教室培训, 地点武汉

    2014年8月26日9:00 – 17:00 2014年8月27日9:00 – 12:00 培训地点: Ø 湖北工业大学 实训楼605教室 Ø 地址:武汉市武昌区南湖李家墩一村一号 Ø 交通路线说明: ...

  4. (LeetCode)二叉树中和为某一值的路径

    原体例如以下: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that addin ...

  5. ExtJs--16--Ext.override()方法专门用来重写对象的方法

    Ext.onReady(function(){ /** * Ext.override()方法专门用来重写对象的方法 */ //定义个类 Ext.define("U",{ //该类的 ...

  6. 网页爬虫框架jsoup介绍

    序言:在不知道jsoup框架前,因为项目需求.须要定时抓取其它站点上的内容.便想到用HttpClient方式获取指定站点的内容.这样的方法比較笨,就是通过url请求指定站点.依据指定站点返回文本解析. ...

  7. 0x3A 博弈论之SG函数

    博弈即玄学啊 (除了nim和二分图博弈什么都不会 算是学了下SG函数吧 这个东西是针对有向图游戏的,相当于把一个局面看作一个点,到达下个局面相当于建一条边 必胜态SG值为0 那么对于一个点,他的SG值 ...

  8. linux下配置虚拟域名

    linux下配置虚拟域名 1.hosts文件位置! /etc/hosts 2.增加一行 127.0.0.1 xxxxx 3.修改apache中的vhosts vi /etc/httpd/extra/h ...

  9. java.lang.NoClassDefFoundError: javax/servlet/ServletInputStream

    转自:https://blog.csdn.net/y970105/article/details/355401 进入 tomcat根目录/lib/servlet-api.jar复制出来,放到JDK_P ...

  10. c++面向对象程序设计 谭浩强 第二章答案

    类体内定义成员函数 #include <iostream> using namespace std; class Time { public: void set_time(); void ...