HDU 5358 First One

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=1nj=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   (1n105) , the number of integers in the array.
The next line contains  n  integers  a1,a2,,an   (0ai105) .
 

Output
For each test case, output the value.
 

Sample Input
   
   
   
   
1 2 1 1
 

Sample Output
   
   
   
   
12

这题时间卡的超紧,必须用nlogn的效率才能跑得过去

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<functional>
using namespace std;
typedef long long ll;
const ll maxn = 100005;
ll n, T, x, sum[maxn], ans;

void read(ll &res)
{
	char ch;
	while ((ch = getchar())<'0' || ch>'9');
	res = ch - '0';
	while ((ch = getchar()) >= '0'&&ch <= '9') res = res * 10 + ch - '0';
}

void write(ll x)
{
	if (x) write(x / 10); else return;
	putchar(x % 10 + '0');
}

bool check(int x, int y, int z)
{
	if (z < 0 || ((sum[y] - sum[x - 1]) >> z) >= 2) return false;
	return true;
}

int main()
{
	read(T);
	while (T--)
	{
		read(n);
		ans = sum[0] = 0;
		for (ll i = 1; i <= n; i++)
		{
			read(x);
			sum[i] = sum[i - 1] + x;
		}
		for (ll i = 0; sum[n] >> i; i++)
		{
			for (ll j = 1, l = 1, r = 1; j <= n; j++)
			{
				while (l < j || check(j, l, i - 1) && l <= n) l++;
				while (check(j, r, i) && r <= n) r++;
				ans += (i + 1)*(j + l + j + r - 1)*(r - l) >> 1;
			}
		}
		write(ans);
		putchar(10);
	}
	return 0;
}


你可能感兴趣的:(HDU)