Minimum Sum

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4611    Accepted Submission(s): 1046

Problem Description
You are given N positive integers, denoted as x0, x1 ... xN-1. Then give you some intervals [l, r]. For each interval, you need to find a number x to make as small as possible!
 
Input
The first line is an integer T (T <= 10), indicating the number of test cases. For each test case, an integer N (1 <= N <= 100,000) comes first. Then comes N positive integers x (1 <= x <= 1,000, 000,000) in the next line. Finally, comes an integer Q (1 <= Q <= 100,000), indicting there are Q queries. Each query consists of two integers l, r (0 <= l <= r < N), meaning the interval you should deal with.

 
Output
For the k-th test case, first output “Case #k:” in a separate line. Then output Q lines, each line is the minimum value of . Output a blank line after every test case.
 
Sample Input
2

5
3 6 2 2 4
2
1 4
0 2

2
7 7
2
0 1
1 1

 
Sample Output
Case #1:
6
4

Case #2:
0
0

 
Author
standy
 
 
裸题我都不会  我废了
 
现在还是懵逼状态
 
ans=  【L,R 】  (中位数左边的值-中位数右边的值 ) 如果 注意一下这个区间元素的个数
用一个sum数组累加  
当进入左子树查找时ans+=查询区间进入右子树的元素和
当进入右子树查询时ans-=查询区间进入左子树的元素和。
 
 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + ;
int sorted[maxn];
int num[][maxn], val[][maxn];
LL sum[][maxn]; void build(int l, int r, int dep) {
if (l == r) {
sum[dep][l] = sum[dep][l - ] + val[dep][l];
return ;
}
int mid = (l + r) >> , same = mid - l + ;
for (int i = l ; i <= r ; i++) {
if (val[dep][i] < sorted[mid]) same--;
sum[dep][i] += sum[dep][i - ] + val[dep][i];
}
int lpos = l, rpos = mid + ;
for (int i = l ; i <= r ; i++) {
if (val[dep][i] < sorted[mid]) val[dep + ][lpos++] = val[dep][i];
else if (val[dep][i] == sorted[mid] && same > ) {
val[dep + ][lpos++] = val[dep][i];
same--;
} else val[dep + ][rpos++] = val[dep][i];
num[dep][i] = num[dep][l - ] + lpos - l;
}
build(l, mid, dep + ) ;
build(mid + , r, dep + );
}
LL ans; int query(int L, int R, int l, int r, int dep, int k) {
if (l == r) return val[dep][l];
int mid = (L + R) >> ;
int cnt = num[dep][r] - num[dep][l - ];
if (cnt >= k) {
int ee = r - L + - (num[dep][r] - num[dep][L - ]) + mid;
int ss = l - L - (num[dep][l - ] - num[dep][L - ]) + mid;
ans += sum[dep + ][ee] - sum[dep + ][ss];
int newl = L + num[dep][l - ] - num[dep][L - ];
int newr = newl + cnt - ;
return query(L, mid, newl, newr, dep + , k);
} else {
int s = L + num[dep][l - ] - num[dep][L - ];
int e = s + cnt - ;
ans -= sum[dep + ][e] - sum[dep + ][s - ];
int newr = r + num[dep][R] - num[dep][r];
int newl = newr - (r - l + - cnt) + ;
return query(mid + , R, newl, newr, dep + , k - cnt);
}
} int main() {
int t, n, cas = , m, l, r;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
memset(val, , sizeof(val));
memset(sum, , sizeof(sum));
for (int i = ; i <= n ; i++) {
scanf("%d", &val[][i]);
sorted[i] = val[][i];
}
sort(sorted + , sorted + n + );
build(, n, );
printf("Case #%d:\n", cas++);
scanf("%d", &m);
while(m--) {
scanf("%d%d", &l, &r);
ans = ;
l++, r++;
int temp = query(, n, l, r, , (l + r) / - l + );
if ((l + r) % ) ans -= temp;
printf("%lld\n", ans);
}
printf("\n");
}
return ;
}

hdu 3473 (划分树)2的更多相关文章

  1. hdu 3473 划分树

    Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  2. HDU 4417 (划分树+区间小于k统计)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个区间,以及一个k值,求该区间内小于等于k值的数的个数.注意区间是从0开始的 ...

  3. hdu 4251 划分树

    思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath ...

  4. hdu 2665 划分树

    思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstring> #include<cstd ...

  5. hdu 4417 划分树

    思路:二分枚举区间第k大.用划分树查找是否符合要求的高度. #include<iostream> #include<algorithm> #include<cstdio& ...

  6. HDU 4417 划分树写法

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  7. HDU 4417 划分树+二分

    题意:有n个数.m个询问(l,r,k),问在区间[l,r] 有多少个数小于等于k. 划分树--查找区间第k大的数.... 利用划分树的性质.二分查找在区间[l,r]小于等于k的个数. 假设在区间第 i ...

  8. hdu 2665 划分树模板题(可作为模板)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. HDU 3473 Minimum Sum 划分树,数据结构 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...

  10. HDU 3473 Minimum Sum (划分树)

    题意:给定一个数组,有Q次的询问,每次询问的格式为(l,r),表示求区间中一个数x,使得sum = sigma|x - xi|最小(i在[l,r]之间),输出最小的sum. 思路:本题一定是要O(nl ...

随机推荐

  1. python 面向对象 (多态)

    什么是多态?多态就像是人有多种心情,场景不一样心情就会不一样. class Dog: def print_self(self): print('this is dog') class Hsq(Dog) ...

  2. (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现

    前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...

  3. 介绍PHP的自动加载

    昨天面试被问到了 PHP 的自动加载机制,因为很多概念模糊啦,没回答好,今天特意来总结一下. include 和 require 是PHP中引入文件的两个基本方法,但是每个脚本的开头,都需要包含(in ...

  4. CSS3复选框动画

    本示例实现了两种单选按钮动画效果,一种是移动,一种是滑块,以下是html布局以及css样式 html:这里使用了label标签的for属性,以此来绑定radio <div class=" ...

  5. stm32--USB(作为U盘)+FatFs的实现

    一.USB功能的添加(作为U盘) 添加文件 将官方库中的Library文件夹中的所有有效文件添加到工程中,分为4个文件夹: usb class为硬件相关(Library\Class): usb dri ...

  6. kindeditor 限制上传图片大小及宽高

    进入:/kindeditor/plugins/image/image.js,替换其中的 self.plugin.imageDialog = function (options)方法,代码为: self ...

  7. Linux-Shell脚本编程-学习-3-Shell编程-shell脚本基本格式

    前面两篇文章基本介绍了一部分linux下的基本命令,后面还需要大家自行了解下linux的文件系统的磁盘管理部分,这里就不在写了. 什么是shell编程,我也解释不来,什么是shell脚本了,我理解就是 ...

  8. Python 3基础教程23-多维列表

    这里简单举例一个多维列表,多维看起来都很晕. # 多维列表 x = [ [5,6],[6,7],[7,2] ,[2,5] ,[4,9]] print(x) # 根据索引引用列表元素,例如打印[6,7] ...

  9. Spark概念介绍

    Spark概念介绍:spark应用程序在集群中以一系列独立的线程运行,通过驱动器程序(Driver Program)发起一系列的并行操作.SparkContext对象作为中间的连接对象,通过Spark ...

  10. [Linux] 服务器镜像定时备份解决方案 crontab+rsync+flock

    两台服务器定时同步文件解决方案: 环境: 主机:192.168.1.1 镜像机:192.168.1.2 需要将主机内容备份至镜像机(假设用户都为root) 备份内容为 /export 目录下所有内容至 ...