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 a1,a2,…,an.
Let S(i,j) be
the sum of ai,ai+1,…,aj.
Now soda wants to know the value below:

∑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).
 
Output
For each test case, output the value.
 
Sample Input
1
2
1 1
 
Sample Output
12
 
Source

首先题意不是啥问题,就是给你个数组,让你求那个式子,s表示i到j的和。

比赛的时候想了个带二分的,就是统计log2可能出现的可能,一共同拥有34种,然后求一个前缀和,前缀和是递增的,能够二分。就写了

复杂度没算好,以为33*n*log(n)能过。结果跪了一下午,昨天就这么愉快的跪了

赛后题解上说用俩指针扫一遍,不得不吐槽一下。MD题解都是英文的。

联想到一次bestcoder 有一个题是求一共序列中两个数的和模上一个数最大,我以前的做法就是排序二分。而正解就是俩指针扫一遍,然而我没有记住

这个题就卡这个log(n)然而我就是过不去,诶。还是思维被限制住了

今天上午搞了个33 * n的

思路:

把数组处理成 前缀和,把log分类,有35种情况,题中吧log(0) 规为0。须要特判,题中给的最大的sum值为10^10,所以有35种情况,

那么就分情况讨论,一层循环。里面就是枚举n。然后找到两个值一个是sum[i-1] + 2^j的位置。另一个是sum[i-1]+2^(j+1)的位置,这段区间内的log值就全为j,用等差数列求和公式就能瞬间算出来这段区间的值,并且仅仅须要两个标记扫一遍。为何能够仅仅扫一遍呢,sum数组的值是递增的。须要找的值也是递增的。所下面次找的时候仅仅须要在上次寻找的后面继续接上就OK

/****************************************
** 2015 Multi-University Training Contest 6
** 1006 First One
** HDU 5358
** by calamity_coming
**************************************/ #include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int MAX_LONG = 1E5;
ll a[MAX_LONG + 10];
ll sum[MAX_LONG + 10];
ll cf2[40]; void init()
{
ll k = 1;
for(int i=0; i<=34; ++i)
{
cf2[i] = (k<<(i));
}
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
sum[0] = 0;
for(int i=1; i<=n; ++i)
{
scanf("%I64d",&a[i]);
sum[i] = sum[i-1] + a[i];//前缀和处理
}
sum[n+1] = 1E17;
ll ans = 0; //0
for(int i=1; i<=n; ++i)//0比較特殊。要特殊的干
{
int p = i;
while(sum[p]==sum[i-1] && p<=n+1)
{
++p;
}
--p;
if(p>=i)
{
ans += (ll)(i*3+p)*(ll)(p-i+1)/2;
}
} for(int j=0; j<=33; ++j)//这是每一个情况
{
int p1 = 0,p2 = 0;//用两个指针扫一遍
for(int i=1; i<=n; ++i)//当i递增时,新的p1,p2一定在后面
{
ll adc = sum[i-1] + cf2[j];
while(sum[p1]<adc && p1<=n)
{
++p1;
}
adc = sum[i-1] +cf2[j+1];
while(sum[p2]<adc && p2<=n+1)
{
++p2;
}
--p2;
if(p2>=p1 && p2)
{
ans += (j+1)*(ll)(i*2+p1+p2)*(ll)(p2-p1+1)/2;
}
}
}
printf("%I64d\n",ans);
}
return 0;
}

HDU 5358 多校第6场 First One的更多相关文章

  1. HDU 4635 多校第四场 1004 强联通

    我还有什么好说,还有什么好说...... 我是SBSBSBSBSBSBSBSBSBSBSBSBBSBSBSBSBSBSBSBSBS........................ 题意 思路什么的都不 ...

  2. HDU 4622 多校第三场1002 后缀自动机

    比赛的时候我是用后缀数组的,但是T了. 赛后看了解题报告说,后缀数组貌似是卡你常数的时间,我算了下复杂度O(T * Q * n).这是10 ^ 8,但是考虑到每次询问的时候都要重新构造字符,所以那个n ...

  3. HDU 4628 多校第三场1008 dp

    这题就没什么好说的了.直接枚举2 ^ 16 的状态,用1表示拿这位,0表示不拿,每次判断是否可以这么拿. #include <iostream> #include <cstdio&g ...

  4. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  5. HDU暑假多校第八场J-Taotao Picks Apples

    一.题意 给定一个序列,之后给出若干个修改,修改的内容为在原序列的基础上,将某一位元素的值改成给定的值<每次修改相互独立,不保存修改后的结果>.之后询问,在选择第一位元素的情况下,最长递增 ...

  6. HDU暑假多校第六场K-werewolf

    一.题意 好人必然说真话,坏人不一定说真话,给定N个人的言论<每人一个发言.不谈及自己>,要求指出有多少个人一定是好人,有多少个人一定是坏人.#define 狼人 坏人#define 村民 ...

  7. HDU暑假多校第三场H.Monster Hunter

    一.题意 给定一个树状地图,每个树节点上有一只怪物,打死一只怪物的过程中将会消耗A点HP,打死之后将会获得B点HP.因为树状结构,所以每只怪物必须先打死父节点的怪兽之后在打死子节点的怪物.现在,给定每 ...

  8. HDU暑假多校第四场J-Let Sudoku Rotate

    一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...

  9. HDU 全国多校第四场 题解

    题解 A AND Minimum Spanning Tree 参考代码: #include<bits/stdc++.h> #define maxl 200010 using namespa ...

随机推荐

  1. CF814B An express train to reveries

    思路: 模拟,枚举. 实现: #include <iostream> using namespace std; ; int a[N], b[N], cnt[N], n, x, y; int ...

  2. Android RecyclerView嵌套EditView实时更新Item数据

    一.场景(例如:购物车) 1.当我们需要以列表样式管理某些数据时,可能需要列表项的某个字段可编辑 2.编辑Item上的某个字段后可能还要更新相关字段的值 二.可能遇到的问题 1.列表滑动导致输入框中的 ...

  3. glassfish中新建数据源(创建数据库连接池)

    1.浏览器输入:http://localhost:4848 登录glassfish域管理控制台,默认的用户名和密码是amin和adminadmin.(也可以通过NetBeans的服务选项卡--服务器- ...

  4. Spring+Spring MVC+Hibernate增查(使用注解)

    使用Spring+Spring MVC+Hibernate做增删改查开发效率真的很高.使用Hibernate简化了JDBC连接数据库的的重复性代码.下面根据自己做的一个简单的增加和查询,把一些难点分析 ...

  5. HDU_1166_敌兵布阵

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. CAD保存文件为各种格式

    <p class="mtext"> 主要用到函数说明:</p><p style="line-height: 0.6;"> & ...

  7. Java基础——面向对象(封装——继承——多态 )

    对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...

  8. NAT、NAPT(PAT)的基本概念和工作原理及区别

    转自:http://blog.sina.com.cn/s/blog_5d302bd20100gprv.html 近年来,随着 Internet 的迅猛发展,连入 Internet 的主机数量成倍增长. ...

  9. Python学习笔记(3)动态类型

    is运算符 ==是值相等而is必须是相同的引用才可以 l=[1,2,3] m=[1,2,3] print(l==m) # True print(l is m) # False sys模块 getref ...

  10. 山建校赛B题公式证明

    原题 证明