[区间合并,优化] hdu5358多校联合 第六场 First one
2015-08-07 10:01
351 查看
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. 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
2015 Multi-University Training Contest 6
由于下取整log(sum)的值是很小的。可以枚举每个位置为开始位置,然后枚举每个log(sum)只需36*n的。后面的i+j累加和也可以推公式推出来。
但是找log值相同的区间,需要用log(sum)*n的复杂度预处理出来,如果每次二分位置会超时。
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. 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
2015 Multi-University Training Contest 6
由于下取整log(sum)的值是很小的。可以枚举每个位置为开始位置,然后枚举每个log(sum)只需36*n的。后面的i+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 = 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; }
相关文章推荐
- js 关于在子类构造函数中加入call(this)的用意!
- Web前端开发大系概览 (迄今为止最全的互联网前端开发技术栈)
- 记忆存储的生理单元
- 南邮 OJ 1917 松牛的故事1
- 南邮 OJ 1916 贲神的故事2
- svn linux命令
- iOS开发 - XCode设置断点与编辑断点
- [办公自动化]windows7 仿宋GB2312字体打印不对
- 写后台SQL的一些心得
- tomcat的几种部署方法
- 【Android杂谈】安卓开发模拟按键-坐标万能版(二)
- 白盒测试的作用
- 数据结构之树和二叉树---二叉树的基本操作
- manifest配置权限区分大小写
- 《游戏程序设计模式》 2 - 顺序模式
- DevExpress v15.1:TestCafe功能升级
- HDU1.3.8 As Easy As A+B
- 程序员修炼之道系列 - 参与的开源项目和阅读的书籍
- MySQL触发器、存储过程、自定义函数、视图 常用SQL
- Linux系统命令及Shell脚本学习笔记一:Linux简介