1 2 1 1
12
能够枚举每一个位置为開始位置,然后枚举每一个log(sum)仅仅需36*n的。
中间j的累加和
推公式就可以。
可是找log值同样的区间,须要用log(sum)*n的复杂度预处理出来,假设每次二分位置会超时。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define maxn 100007
ll num[maxn];
ll pos[maxn][36];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for(int i = 0;i < n; i++){
scanf("%I64d",&num[i]);
}
num[n] = 0;
for(ll i = 0;i < 36; i++){
ll di = 1LL<<(i+1);
ll su = num[0];
int p = 0;
for(int j = 0;j < n; j++){
if(j) su -= num[j-1];
while(su < di && p < n){
su += num[++p];
}
pos[j][i] = p;
}
}
ll ans = 0,res;
for(int i = 0;i < n; i++){
ll p = i,q;
for(int j = 0;j < 36 ;j ++){
q = pos[i][j];
res = (j+1)*((i+1)*(q-p)+(p+q+1)*(q-p)/2);
ans += res;
p = q;
}
}
printf("%I64d\n",ans);
}
return 0;
}
hdu 5358 First One 2015多校联合训练赛#6 枚举
原文:http://www.cnblogs.com/claireyuancy/p/7151945.html