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. 数据库中pymysql模块的使用

    pymysql 模块 使用步骤: 核心类Connect链接用和Cursor读写用 1. 与数据库服务器建立链接 2. 获取游标对象(用于发送和接收数据) 3. 用游标执行sql语句 4. 使用fetc ...

  2. Leecode刷题之旅-C语言/python-1.两数之和

    开学后忙的焦头烂额(懒得很),正式开始刷leecode的题目了. 想了想c语言是最最基础的语言,虽然有很多其他语言很简单,有更多的函数可以用,但c语言能煅炼下自己的思考能力.python则是最流行的语 ...

  3. Qt——菜单栏、工具栏、状态栏

    1.菜单栏 菜单栏的意义是将可点击触发最终事件的集中在一起,所以菜单栏中是QAction 添加菜单栏是QMainWindow的行为 QMenubar *menubar = this->addMe ...

  4. 函数:引用file类对象及io类对象作为参数打印文本及显示文本

    #include <iostream> #include <fstream> #include <cstdlib> using namespace std; voi ...

  5. Hbase数据IO

    场景及方案分析 场景1:logs --> HBase logs -> flume -> hfile -> import -> HBase (实时) csv导入HBase ...

  6. 使用LinqToExcel和EPPlus操作excel

    1.使用LinqToExcel LinqToExcel是一个.net framework平台下开源项目,它主要实现了LINQ的语法查询Excel电子表格.类型之前的LINQToXXX如果你是LINQ语 ...

  7. 从webview中加载assets中的html文件

    private void readHtmlFormAssets(){ WebSettings webSettings = tipsWebView.getSettings(); webSettings. ...

  8. Python进程、线程、协程及IO多路复用

    详情戳击下方链接 Python之进程.线程.协程 python之IO多路复用

  9. 安装mathtype出问题卸载后 office2016打开mathtype弹错误窗口

    解决方法:找到 C:\Program Files (x86)\Microsoft Office\root\Office16\STARTUP目录下的MathType Commands 6 For Wor ...

  10. SSH公钥认证(码云)

    开发者向码云版本库写入最常用到的协议是 SSH 协议,因为 SSH 协议使用公钥认证,可以实现无口令访问,而若使用 HTTPS 协议每次身份认证时都需要提供口令.使用 SSH 公钥认证,就涉及到公钥的 ...