[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 ...
随机推荐
- PPT五大插件汇总下载
收集总结一下PPT制作中常用到的插件/应用,希望能帮到大家. 1.Nordri Tools NT插件是由Nordri公司开发的PPT插件,功能强大,简单易上手,设计偷懒必备神器.我们可以看看它有哪些功 ...
- UVA10972 - RevolC FaeLoN(双连通分量)
题目链接 题意: 给定一个无向图,问最少加入多少条边,使得这个图成为连通图 思路:首先注意题目给出的无向图可能是非连通的,即存在孤立点.处理孤立点之后.其它就能够当作连通块来处理.事实上跟POJ335 ...
- QTableWidget的使用和美工总结
基本外观设置 FriendTable->setFrameShape(QFrame::NoFrame); //设置边框 FriendTable->setHorizontalHeaderLa ...
- 了解Unicode编码
制定Unicode编码标准的组织有两个,一个是国际标准化组织ISO,一个是多语言软件制造商组成的统一码联盟. 通用字符集UCS(Universal Character Set)是由ISO制定的编码方案 ...
- xslt语法之---基础语法
1. XSLT常用元素: 1.1 <xsl:template>:创建模板 Match属性的作用是使模板和XML元素相关联 <xsl:template match=" ...
- Java 单文件下载及重命名
代码(仅供参考): /* * 另存为 */ @RequestMapping("/saveAs.do") public @ResponseBody void saveAs(Strin ...
- CakePHP的blog教程三
简单的身份验证和授权应用 接着我们blog教程的例子,如果我们想要建立一个根据登录的用户身份来决定其安全访问到正确的urls. 同时我们还有其他的需求: 允许我们的blog有多个作者,每一个作者都可以 ...
- jsp页面表单的遍历要怎么写
1.传统的方式使用request.getAttribute(“list”);获取表单的值, 2.也可以用struts2提供的标签进行遍历 备注 // 传统的接受参数方法 // String sfz=t ...
- C# string转int
1,int转成string用toString 或者Convert.toString()如下 例如:int varInt = 1; string varString = Convert.ToString ...
- What's the use of @ before the path defination
When you define your path const : const string Child_Medical_Pdf = @"~/Media/ChildPdf"; Th ...