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. 最长公共子序列(Swift版本)

    class Mark {     var count: Int     var type: Int         init(count: Int, type: Int) {         self ...

  2. Java-2-学习历程2:基础知识1,2,3文档、完整版视频资源、电子书籍下载

     Java学习历程:基础知识1,2,3文档.完整版视频资源.电子书籍 1.基础知识1,2.3可到下面地址下载: http://download.csdn.net/detail/iot_li/886 ...

  3. iOS~判断应用是否有定位权限

    在特定场景下我们需要判断用户是否允许应用获取定位权限 1.导入类库: #import <CoreLocation/CLLocationManager.h> 2.判断用户手机是否开启了定位服 ...

  4. 剑指offer——02替换空格(Python3)

    思路:Python列表中实现字符串的替换,涉及到频繁的插入操作,在数据结构中线性表分为顺序表和链表,顺序表的适合频繁的查询,链表适合频繁的插入和删除.综上所述,本题使用链表来实现. 我们从字符串的后面 ...

  5. IOC-Castle Windsor映射

    Castle最早在2003年诞生于Apache Avalon项目,目的是为了创建一个IOC(控制反转)框架.发展到现在已经有四个组件了,分别是ActiveRecord(ORM组件),Windsor(I ...

  6. 在.NetCore2.0中使用Swagger

    一.新建.netCore webapi项目 二.安装swagger ,通过 Package Manager 控制台:Install-Package SwashBuckle.AspNetCore -Pr ...

  7. linux 下vim中关于删除某段,某行,或者全部删除的命令

  8. EL表达式的作用与限制条件

    限制条件 只能访问域对象的数据 用法 访问基本数据类型 首先把数据保存在域对象中 pagecontext.setAttribute("name","eric") ...

  9. Facebook再次爆出安全漏洞,9000万用户受影响

    今年上半年开始,美国社交媒体Facebook因数据泄露事件和涉嫌操纵选举等问题频繁接受听证会拷问,然而事情却远没有结束.今年9月Facebook再次爆出安全漏洞,导致9000万用户可能受到影响. 根据 ...

  10. 基础——(4)SR Latch(SR锁存器)

    Digital logic gets really interesting when we connect the output of gates back to an input. The SR l ...