[BZOJ 3110] [Zjoi2013] K大数查询 【树套树】
题目链接: BZOJ - 3110
题目分析
这道题是一道树套树的典型题目,我们使用线段树套线段树,一层是区间线段树,一层是权值线段树。一般的思路是外层用区间线段树,内层用权值线段树,但是这样貌似会很难写。多数题解都使用了外层权值线段树,内层区间线段树,于是我就这样写了。每次插入会在 logn 棵线段树中一共建 log^2(n) 个结点,所以空间应该开到 O(nlog^2(n)) 。由于这道题查询的是区间第 k 大,所以我们存在线段树中的数值是输入数值的相反数(再加上 n 使其为正数),这样查第 k 小就可以了。在查询区间第 k 大值的时候,我们用类似二分的方法,一层一层地逼近答案。
写代码的时候出现的错误:在每一棵区间线段树中修改数值的时候,应该调用的是像 Insert(Lc[x], 1, n, l, r) 这样子,但我经常写成 Insert(x << 1, s, t, l, r) 之类的。注意!
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 100000 + 5, MaxM = 100000 * 16 * 16 + 5; int n, m, f, a, b, c, Index, Ans;
int Root[MaxN * 4], Lc[MaxM], Rc[MaxM], Sum[MaxM], Lazy[MaxM]; inline int gmin(int a, int b) {
return a < b ? a : b;
}
inline int gmax(int a, int b) {
return a > b ? a : b;
} int Get(int x, int s, int t, int l, int r) {
if (l <= s && r >= t) return Sum[x];
int p = 0, q = 0, m = (s + t) >> 1;
if (l <= m) p = Get(Lc[x], s, m, l, r);
if (r >= m + 1) q = Get(Rc[x], m + 1, t, l, r);
return (p + q + Lazy[x] * (gmin(t, r) - gmax(s, l) + 1));
} int GetKth(int l, int r, int k) {
int s = 1, t = n * 2, m, x = 1, Temp;
while (s != t) {
m = (s + t) >> 1;
if ((Temp = Get(Root[x << 1], 1, n, l, r)) >= k) {
t = m; x = x << 1;
}
else {
s = m + 1; x = x << 1 | 1; k -= Temp;
}
}
return s;
} void Insert(int &x, int s, int t, int l, int r) {
if (x == 0) x = ++Index;
if (l <= s && r >= t) {
Sum[x] += t - s + 1;
++Lazy[x];
return;
}
int m = (s + t) >> 1;
if (l <= m) Insert(Lc[x], s, m, l, r);
if (r >= m + 1) Insert(Rc[x], m + 1, t, l, r);
Sum[x] = Sum[Lc[x]] + Sum[Rc[x]] + Lazy[x] * (t - s + 1);
} void Add(int l, int r, int Num) {
int s = 1, t = n * 2, m, x = 1;
while (s != t) {
Insert(Root[x], 1, n, l, r);
m = (s + t) >> 1;
if (Num <= m) {
t = m;
x = x << 1;
}
else {
s = m + 1;
x = x << 1 | 1;
}
}
Insert(Root[x], 1, n, l, r);
} int main()
{
scanf("%d%d", &n, &m);
Index = 0;
for (int i = 1; i <= m; ++i) {
scanf("%d%d%d%d", &f, &a, &b, &c);
if (f == 1) {
c = -c + n + 1;
Add(a, b, c);
}
else {
Ans = GetKth(a, b, c);
Ans = -Ans + n + 1;
printf("%d\n", Ans);
}
}
return 0;
}
[BZOJ 3110] [Zjoi2013] K大数查询 【树套树】的更多相关文章
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
- BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )
BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
- BZOJ 3110 [Zjoi2013]K大数查询(整体二分)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 11654 Solved: 3505[Submit][St ...
- bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】
树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...
- BZOJ 3110 [Zjoi2013]K大数查询 ——树套树
[题目分析] 外层区间线段树,内层是动态开点的权值线段树. SY神犇说树套树注重的是内外层的数据结构的选择问题,果然很重要啊. 动态开点的实现方法很好. [代码] #include <cstdi ...
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
随机推荐
- BloomFilter--大规模数据处理利器
Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合. 一. 实例 为了说明Bl ...
- MS SQL 性能优化
http://blog.csdn.net/dba_huangzj/article/details/50455543
- 廖雪锋笔记1---python变量类型
整型:a/b a//b a%b 浮点型:.2 字符串: "" '' r"" r'' '''...''' r'''...'''' 变量值共享:写时复制 NULL型 ...
- 蓝牙代理报错:invalid handle error
错误症状: -(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCh ...
- SQL Server2005 表分区三步曲(zz)
前言 SQL Server 2005开始支持表分区,这种技术允许所有的表分区都保存在同一台服务器上.每一个表分区都和在某个文件 组(filegroup)中的单个文件关联.同样的一个文件/文件组可以容纳 ...
- Android布局管理器(线性布局)
线性布局有LinearLayout类来代表,Android的线性布局和Swing的Box有点相似(他们都会将容器里面的组件一个接一个的排列起来),LinearLayout中,使用android:ori ...
- wordpress 当前栏目名,当前栏目的分类名
wordpress在设计主题和做模板时经常会用到调用当前分类栏目名称,常见的有当前栏目页.文章页,详情代码如下: 1.分类名称与链接 <?php the_category(); ?> 2. ...
- JS & JQuery 动态添加 select option
因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接有时候会失效,所以 ...
- js正则验证方法大全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- removing right click context menu options on recycle bin
Humpty is correct as always First you might want to make a backup of the reg key then remove the Wa ...