传送门

之前看挑战的时候看到一道分桶法的题目,其实我不是很明白分桶法应该怎么写。看到poj后面的讨论版上写着划分树裸题,而我以前就听说过了划分树,就干脆拿来学习一下。在写这篇博客的时候,其实我还是对这个东西不是很明白。在此先mark一下,以便日后再次学习。

划分树是利用模拟快速排序的方法,以树状结构保存信息的数据结构。作用是快速查找区间内第k大的值,我目前学习下来,应该是不能在线操作的。至于划分树怎么写,各位大能菊苣非常多,先贴上一个传送门。

别人的划分树链接

hdu这道题也算是划分树的裸题了吧,就是需要在查询的时候同时保存一下小于等于中位数的数的个数以及其和,比poj的板子题稍微强一点。我也是参考了别人的代码才能够通过的。

附上poj板子题

关于这个划分树模板,我是根据百度百科上的模板修改的,感觉原作者写得挺好的。

/*****************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define offcin ios::sync_with_stdio(false)
#define sigma_size 26
#define lson l,m,v<<1
#define rson m+1,r,v<<1|1
#define slch v<<1
#define srch v<<1|1
#define sgetmid int m = (l+r)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define pb push_back
#define fi first
#define se second const int INF = 0x3f3f3f3f;
const LL INFF = 1e18;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-9;
const LL mod = 1e9+7;
const int maxmat = 10;
const ull BASE = 31; /*****************************************************/ const int maxn = 1e5 + 5;
int a[maxn], s[maxn];
int seg[20][maxn], num[20][maxn];
LL sum[20][maxn];
LL Sum[maxn];
int N, M;
void build(int l, int r, int v) {
sgetmid;
int lm = m - l + 1, lp = l, rp = m + 1;
for (int i = l; i <= m; i ++) lm -= s[i] < s[m];
for (int i = l; i <= r; i ++) {
num[v][i] = i == l ? 0 : num[v][i - 1];
sum[v][i] = i == l ? 0 : sum[v][i - 1];
if (seg[v][i] == s[m]) {
if (lm) {
lm --;
num[v][i] ++;
sum[v][i] += seg[v][i];
seg[v + 1][lp ++] = seg[v][i];
}
else seg[v + 1][rp ++] = seg[v][i];
}
else if (seg[v][i] < s[m]) {
num[v][i] ++;
sum[v][i] += seg[v][i];
seg[v + 1][lp ++] = seg[v][i];
}
else seg[v + 1][rp ++] = seg[v][i];
}
if (l < r) {
build(l, m, v + 1);
build(m + 1, r, v + 1);
}
}
LL suml, numl;
int query(int L, int R, int x, int l, int r, int v) {
if (l == r) return seg[v][l];
int s, ss; sgetmid;
LL tmp = 0;
if (l == L) s = 0, ss = num[v][R], tmp = sum[v][R];
else s = num[v][L - 1], ss = num[v][R] - s, tmp = sum[v][R] - sum[v][L - 1];
if (x <= ss) return query(l + s, l + s + ss - 1, x, l, m, v + 1);
else {
suml += tmp;
numl += ss;
return query(m + L - l - s + 1, m + R - l - s - ss + 1, x - ss, m + 1, r, v + 1);
}
}
LL getans(int l, int r) {
suml = numl = 0;
int k = query(l, r, (r - l) / 2 + 1, 1, N, 0);
LL ans = (LL)k * numl - suml;
suml = Sum[r] - Sum[l - 1] - suml;
numl = r - l + 1 - numl;
ans += suml - numl * (LL)k;
return ans;
}
int main(int argc, char const *argv[]) {
int T, kase = 1;
cin>>T;
while (T --) {
mem(Sum, 0);
scanf("%d", &N);
for (int i = 1; i <= N; i ++) {
scanf("%d", a + i);
s[i] = seg[0][i] = a[i];
Sum[i] = Sum[i - 1] + a[i];
}
sort(s + 1, s + N + 1);
build(1, N, 0);
scanf("%d", &M);
printf("Case #%d:\n", kase ++);
while (M --) {
int l, r;
scanf("%d%d", &l, &r); l ++, r ++;
printf("%I64d\n", getans(l, r));
}
puts("");
}
return 0;
}

hdu 3473 Minimum Sum的更多相关文章

  1. HDU 3473 Minimum Sum(划分树)

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

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

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

  3. HDU 3473 Minimum Sum (划分树)

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

  4. HDU 3473 Minimum Sum (划分树求区间第k大带求和)(转)

    题意:在区间中找一个数,求出该区间每个数与这个数距离的总和,使其最小 找的数字是中位数(若是偶数个,则中间随便哪个都可)接着找到该区间比此数大的数的总和 区间中位数可以使用划分树,然后在其中记录:每层 ...

  5. HDU 3473 Minimum Sum 划分树

    题意: 给出一个长度为\(n(1 \leq n \leq 10^5)\)的序列\(a\) 有若干次查询l r:找到一个\(x\)使得\(\sum \limits_{l \leq i \leq r} \ ...

  6. HDOJ 3473 Minimum Sum

    划分树,统计每层移到左边的数的和. Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  7. 【HDOJ】3473 Minimum Sum

    划分树解.主席树解MLE. /* 3473 */ #include <iostream> #include <sstream> #include <string> ...

  8. hdu 3473 划分树

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

  9. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

随机推荐

  1. YUV格式分析

    转自:http://www.cnblogs.com/armlinux/archive/2012/02/15/2396763.html Andrew Huang <bluedrum@163.com ...

  2. js爬虫

    1.爬虫相关的包 (1)const request =  require('superagent'); // 处理get post put delete head 请求  轻量接http请求库,模仿浏 ...

  3. 关于php留言本网站的搭建

    1.检查php,http服务是否安装 [root@localhost ~]# rpm -qa | grep http httpd-tools--.el7.centos.x86_64 httpd--.e ...

  4. DllImport attribute的总结

    C#有没有方法可以直接都用已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法),而不需要重新编写代码? 答案是肯定,就是通过接下来要说的 DllImport . DllImp ...

  5. 【STL】优先队列priority_queue详解+OpenJudge-4980拯救行动

    一.关于优先队列 队列(queue)这种东西广大OIer应该都不陌生,或者说,队列都不会你还学个卵啊(╯‵□′)╯︵┻━┻咳咳,通俗讲,队列是一种只允许从前端(队头)删除元素.从后端(队尾)插入元素的 ...

  6. Json解析实例

    using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Win ...

  7. Hibernate的映射文件配置

    对象关系的映射是用一个XML文档来说明的.映射文档可以使用工具来生成,如XDoclet,Middlegen和AndroMDA等.下面从一个映射的例子开始讲解映射元素,映射文件的代码如下: <?x ...

  8. 利用反卷积神经网络可视化CNN

    http://blog.csdn.net/hjimce/article/details/51762046 http://arxiv.org/pdf/1311.2901.pdf Visualizing ...

  9. About next_permutation

    哈哈没错这个又是我们C++党的语言优势之一,用这个函数可以求当前排序的下一个排序,也就是说可以方便的求全排列,用这个函数需要用到algorithm这个头文件. 与这个函数相反的是prev_permut ...

  10. 别不信!App三年内将被HTML5顶替彻底消失?

    2007年W3C(万维网联盟)立项HTML5,直至2014年10月底,这个长达八年的规范终于正式封稿. 过去这些年,HTML5颠覆了PC互联网的格局,优化了移动互联网的体验,接下来,HTML5将颠覆原 ...