您的位置:首页 > 其它

hdu5338 (二进制,双指针)

2015-08-07 10:21 302 查看
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = 1<<30;
/*

*/
const int N = 100000 + 10;
int a
;
LL sum
;

int main()
{

int t, n;
scanf("%d", &t);
LL ans;
while (t--)
{
ans = 0;
scanf("%d", &n);
sum[n + 1] = 0;
for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);
for (int i = n; i >= 1; --i)
{
sum[i] = sum[i + 1] + i;
//计算所有的1*(i+j), 因为log取整之后有+1
ans += (LL)(n - i + 1)*i + sum[i];
}

for (int k = 1; k < 40; ++k)
{
LL lim = 1LL << k;
LL s = 0;
for (int i = 1, j = 1; i <= n; ++i)
{
while (j <= n &&s < lim)
s += a[j++];
if (s >= lim)//[i,j-1->n]的区间肯定是大于等于lim的
ans += (LL)(n- j + 2) * i + sum[j - 1];
else
break;
s -= a[i];
}
}
printf("%lld\n", ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: