First One
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2612 Accepted Submission(s): 745
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:
Note: In this problem, you can consider log20 as 0.
∑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) .
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
Author
zimpha@zju
Source
Recommend
wange2014
题意:给你一个整数序列a1,a2,a3,…,an,要求求出的值,S(i,j)表示ai+ai+1+ai+2+…+aj
解题思路:(⌊log2S(i,j)⌋+1)的意思就是S(i,j)化成二进制后的比特位个数,因为S(i,j)不超过10^10,所以比特位不会超过35个。先初始化数组pow2,记录比特位为i的所有数中的第一个数,然后用尺取法枚举每一位有多少个
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <bitset>
#include <set>
#include <vector>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int n;
LL sum[100090], a[100090];
LL pow2[40];
int main()
{
pow2[1] = 0, pow2[2] = 2;
for (int i = 3; i<40; i++)
pow2[i] = pow2[i - 1] << 1;
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
sum[0] = 0;
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]), sum[i] = sum[i - 1] + a[i];
LL ans = 0, temp;
for (int i = 1; i <= 39; i++)
{
if (pow2[i]>sum[n]) break;
int l = 1, r = 0;
temp = 0;
for (int j = 1; j <= n; j++)
{
l = max(l, j), r = max(r, j-1);
while (l <= n&&sum[l] - sum[j - 1]<pow2[i]) l++;
while (r + 1 <= n&&sum[r + 1] - sum[j - 1]<pow2[i + 1]) r++;
if (l <= r) temp +=1LL* (r - l+1)*(r + l ) / 2 + 1LL*j*(r - l + 1);
}
ans +=1LL* temp*i;
}
printf("%lld\n", ans);
}
return 0;
}