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. ruby 数据类型Range

    范围(Range)无处不在:a 到 z. 0 到 9.等等.Ruby 支持范围,并允许我们以不同的方式使用范围: 作为序列的范围 作为条件的范围 作为间隔的范围 作为序列的范围 (1..5) #==& ...

  2. STL——vector和list

    vector和list为STL中的顺序容器,顺序容器会依次维护第一个到最后一个元素,在顺序容器上,我们主要的操作就是迭代. 头文件: #include<vector> #include&l ...

  3. 用filter()筛选出素数

    'use strict'; function get_primes(arr) { return arr.filter(function isPrime(number) { if (typeof num ...

  4. SocketServer模块中的几种类

    BaseServer:包括服务器的核心功能与混合类的一些功能. TCPServer:基本的网络同步TCP服务器. UDPServer:基本的网络同步UDP服务器. ForkingMixIn:实现了核心 ...

  5. 教你如何更改xshell中的转发规则

    使用不同的类型转发,与之对应的端口,所以如果想要使用不同类型的转发就要更改端口使其与之一一对应.本集xshell专栏文章将为大家讲解如何更改转发规则. 更改转发规则操作如下: 1.打开会话对话框. 2 ...

  6. javascript对象转为字符串

    function getStringTime(time){ //年 year = time.getFullYear(); //月 month = time.getMonth() if(String(m ...

  7. Qt Qwdget 汽车仪表知识点拆解8 淡入效果

    先贴上效果图,注意,没有写逻辑,都是乱动的 看下面的开始,开始的时候有一个带入的效果,这里有一个坑, 网上大部分都是调用下面这个函数 setWindowOpacity(); 但是,你会发现,在你的子窗 ...

  8. 第二十篇 sys模块

    修改环境变量 import sys sys.path.append() 但是,这种修复方式只是临时修改 如果要永久修改,就要电脑里配置环境变量. sys.argv:命令行参数List,第一个元素是程序 ...

  9. 常用模块(xml)

    XML(可扩展性标记语言)是一种非常常用的文件类型,主要用于存储和传输数据.在编程中,对XML的操作也非常常见. 本文根据python库文档中的xml.etree.ElementTree类来进行介绍X ...

  10. android问题笔记集

    开发工具:android studio2.2 调试:手机直连调试,版本(android6) 问题1: Error:Unable to start the daemon process. This pr ...