HDU 5358 枚举+尺选

soda has an integer array a1,a2,…,ana1,a2,…,an. Let S(i,j)S(i,j) be the sum of ai,ai+1,…,ajai,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.

InputThere 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 nn (1≤n≤105), the number of integers in the array. 
The next line contains nn integers a1,a2,…,an(0≤ai≤105).OutputFor each test case, output the value.Sample Input

1
2
1 1

Sample Output

12

题意:求一个数组对题目中出现的那个公式的值

做过好几道枚举的题了,但是遇到题还是想不出来使用枚举。

根据题目给的数据范围,我们知道sum(1,n)<=1e10 floor(log2(1e10)) = 33所以我们枚举log2(sum+1)的值,进行尺选就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 1e5+5;
ll s[maxn];
ll low[50], high[50];
int n, x;
ll solve(int k){
    if(s[n]<low[k-1])return 0;
    ll l=1, r=1,num=0;
    for(ll j=1;j<=n;j++){
        l = max(l,j);
        while(l<=n && s[l]-s[j-1]<low[k-1])l++;
        r = max(r,l);
        while(r<=n && s[r]-s[j-1]<=high[k-1])r++;
        if(r>l)
            num += (r-l)*j+(l+r-1)*(r-l)/2;
    }
    return num*k;
}
int main(){
    int t;
    scanf("%d",&t);
    for(int i=1;i<35;i++){
        low[i] = 1ll<<i;
        high[i] = (1ll<<(i+1))-1;
    }
    low[0]=0,high[0]=1;
    while(t--){
        ll ans = 0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&x),s[i] = s[i-1]+x;
        for(int i=1;i<35;i++)
            ans += solve(i);
        printf("%lld\n",ans);
    }
    return 0;
}



原文地址:https://www.cnblogs.com/kongbb/p/10876289.html

时间: 2024-10-15 00:34:56

HDU 5358 枚举+尺选的相关文章

Hdu 5358 First One (尺取法+枚举)

题目链接: Hdu 5358 First One 题目描述: 数组a有n个元素,S[i,j]定义为a[i]+a[i+1]+.....+a[j],问:这个死东西等于多少? 解题思路: 二分肯定超,这个题目的时间卡的炒鸡严格,只有n*log(n)的复杂度才能过,n*log(n)^2都不可以的. 只需要枚举K,并且枚举区间左端i值,计算K的贡献值,然后遍历时候计算一下常数相加即可. 1 #include <cstdio> 2 #include <cstring> 3 #include &

HDU 5358 多校第6场 First One

First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 672    Accepted Submission(s): 193 Problem Description soda has an integer array . Let  be the sum of . Now soda wants to know the va

HDU 1031 Design T-Shirt 选前k大

相当于给出一组数列,然后选择前K大的数的算法. 本题没有给出详细的数据,故此就使用动态分配空间的方法了. 而这种题最好的算法就是使用快排思想,期望时间效率就是O(n)了. 最基本入门解决这种题的算法是直接排序了.那就成了水代码了.用上快排的思想才能体现出水平. 不过这种快排实在考的太多了,建议一定要掌握. 每次做这个算法的题目总会要调试一定时间的,每次都出现奇葩的错误.看来还是不够细心. 做题的时候一定要排除杂念,有干扰,后果很严重,会花长很多时间. 靖空间做题,一定要静,达到一种禅的境界.说禅

HDU 5358(2015多校联合训练赛1006) First One (区间合并+常数优化)

HDU 5358 题意: 求∑?i=1?n??∑?j=i?n??(?log?2??S(i,j)?+1)?(i+j). 思路: S(i,j) < 10^10 < 2^34,所以log2(S)+1的值只可能在1~35之间.由于log变化缓慢的函数特性,我们可以S(i,n)分作多个相同log值的区间来计算,用pos[i][j]预处理记录每个以i为起点,log(s)值为j的区间的右边界,即可优化至nlogn的复杂度. 主要是写起来比较难一些,一些细节比较纠结,一定思路理清后再写. ps.此题卡常数毫无

HDU 5358 First One(枚举+尺举法)

题目链接:传送门 题意:设f(i,j)表示区间[i,j]内元素的和 ,定义 SUM(i,j) = [log2(f(i,j))+1]*(i+j) 求 sigma(sum (i,j)) ( 1<=i<=n,i<=j<=n ) 分析: log2(f(i,j))表示f(i,j)转换为2进制的长度,然后我们经过分析log2(f(i,j))+1的值域 为[1,34]然后我们枚举log2(f(i,j))+1的值,例如我们枚举其值为k,对于一个k我们找到所有满足 条件的区间(i,j),这个条件的代

hdu 5358 First One (尺取法)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5358 题意: 分析:首先要知道[log2(x)]+1代表x的位数,而且根据题意不会超过35,那么枚举位数i:1~35.对于每一位i找到区间[x,y],使得S(x,y)的二进制表示的位数等于i,此时的贡献为i*(x+y).那么对于每一个i,怎么找出所有符合条件的区间[x,y]?1~n枚举起点x,那么y会在一段范围[l,r]内满足条件.下次x变成x+1,即起点x向右移位,那么现在要找的y的区间为[l',r'

HDU 5358 First One 数学+尺取法

多校的题,摆明了数学题,但是没想出来,蠢爆了,之前算了半天的s[i][j]的和,其实是积.其实比赛的时候我连log(s[i][j])+1是s[i][j]的位数都没看出来,说出来都丢人. 知道了这个之后,就枚举二进制数的每一位,因为元素都是非负数,所以sum数组是非降的,这里用到了尺取法,之前也是听说过,应该是做过吧,不太记得了. 因为[2k-1,2k)的位数是k,枚举时,固定左端点,在sum数组找到最小的大于等于2k-1,最大的小于2k的点,这中间的点和左端点的s[i][j]就对于当前的k满足条

HDU 5358 First One(枚举)

这道题如果按照表达式一个个来算肯定超时,下午时候想了一个O(nlogn*logn)的算法,但是t了,因为这道题卡的非常紧几百个样例,必须nlogn的算法才可以ac 回到这道题,考虑log(sum(i,j))+1的特点,可以发现它的值域范围非常小,在1-34之间,那么我们可以考虑枚举log(sum(i,j)+1的值,记为k,然后统计(i+j)的和即可. 对于每一个k,找到所有满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j), 那么我们考虑每个前缀i,找到这个前缀满足2^(k-1)

hdu 5358 First One 2015多校联合训练赛#6 枚举

First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 142    Accepted Submission(s): 37 Problem Description soda has an integer array a1,a2,-,an. Let S(i,j) be the sum of ai,ai+1,-,aj. No