题目链接: 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大数查询 【树套树】的更多相关文章

  1. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

  2. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  3. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  4. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  5. BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

    BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...

  6. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

  7. BZOJ 3110 [Zjoi2013]K大数查询(整体二分)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 11654  Solved: 3505[Submit][St ...

  8. bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】

    树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...

  9. BZOJ 3110 [Zjoi2013]K大数查询 ——树套树

    [题目分析] 外层区间线段树,内层是动态开点的权值线段树. SY神犇说树套树注重的是内外层的数据结构的选择问题,果然很重要啊. 动态开点的实现方法很好. [代码] #include <cstdi ...

  10. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

    有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...

随机推荐

  1. hadoop编程技巧(4)---总体情况key按类别搜索TotalOrderPartitioner

    Hadoop代码测试版:Hadoop2.4 原理:携带MR该程序随机抽样提取前的输入数据,样本分类,然后,MR该过程的中间Partition此值用于当样品排序分组数据.这使得可以实现全球排名的目的. ...

  2. 08_android入门_android-async-http开源项目介绍及用法

    android-async-http开源项目可以是我们轻松的获取网络数据或者向server发送数据.使用起来很easy,关于android-async-http开源项目的介绍内容来自于官方:http: ...

  3. 跟踪MYSQL 的查询优化过程方法

    http://dev.mysql.com/doc/internals/en/tracing-example.html http://blog.chinaunix.net/uid-20785090-id ...

  4. eslint error

    暂时不想解决 报错: 3:16 error Component should be written as a pure function react/prefer-stateless-function ...

  5. 趣谈iOS运行时的方法调用原理

    一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...

  6. FastDFS配置说明(中英文)

    FastDFS配置说明 1)tracker.conf # is this config file disabled # false for enabled # true for disabled di ...

  7. python-集合(第二篇(七):集合)

    第二篇(七):集合   python 集合 集合标准操作 摘要: 说明: ·类似于数学中学的集合,Python中的集合可以实现去重的功能,通过set()函数来实现: ·sets支持x in set, ...

  8. spring集成 log4j + slf4j

    以maven web项目为例, 首先.在pom文件引入相关依赖,如下(spring官网文档有介绍): <dependencies> <!-- spring 相关 --> < ...

  9. java中json转xml

    参考:http://heipark.iteye.com/blog/1394844 需要json-lib-2.1-jdk15.jar和xom-1.2.5.jar,maven pom.xml如下: xml ...

  10. servlet 项目 ,,启动没问题,,但是,一请求也面就报错误。。。。求解决。。。。。。。。。。。。。各种百度,都没解决了啊。。。。。急急急急急急急急急急急急急急急急急急

    信息: Server startup in 1674 mslog4j:WARN No appenders could be found for logger (com.mchange.v2.log.M ...