BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置。这些位置上能够放若干个数字。
如今有两种操作。
1.在区间l到r上加入一个数字x
2.求出l到r上的第k大的数字是什么
思路:这样的题一看就是树套树,关键是怎么套,怎么写。(话说我也不会来着。。)最easy想到的方法就是区间线段树套一个权值线段树。可是区间线段树上的标记就会变得异常复杂。所以我们就反过来套,用权值线段树套区间线段树。
这样改动操作在外线段树上就变成了单点改动。外线段树就不用维护标记了。在里面的区间线段树上维护标记就easy多了。详细实现见代码。
CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50010
#define CNT (r - l + 1)
using namespace std; int total,asks; struct ValSegTree{
ValSegTree *son[2];
int cnt,c; ValSegTree() {
son[0] = son[1] = NULL;
cnt = c = 0;
}
void PushDown(int k) {
if(son[0] == NULL) son[0] = new ValSegTree();
if(son[1] == NULL) son[1] = new ValSegTree();
if(c) {
son[0]->cnt += c * (k - (k >> 1));
son[0]->c += c;
son[1]->cnt += c * (k >> 1);
son[1]->c += c;
c = 0;
}
}
void Modify(int l,int r,int x,int y) {
if(l == x && r == y) {
cnt += CNT;
c++;
return ;
}
PushDown(CNT);
int mid = (l + r) >> 1;
if(y <= mid) son[0]->Modify(l,mid,x,y);
else if(x > mid) son[1]->Modify(mid + 1,r,x,y);
else {
son[0]->Modify(l,mid,x,mid);
son[1]->Modify(mid + 1,r,mid + 1,y);
}
cnt = son[0]->cnt + son[1]->cnt;
}
int Ask(int l,int r,int x,int y) {
if(!cnt) return 0;
if(l == x && r == y) return cnt;
PushDown(CNT);
int mid = (l + r) >> 1;
if(y <= mid) return son[0]->Ask(l,mid,x,y);
if(x > mid) return son[1]->Ask(mid + 1,r,x,y);
int left = son[0]->Ask(l,mid,x,mid);
int right = son[1]->Ask(mid + 1,r,mid + 1,y);
return left + right;
}
};
struct IntSegTree{
IntSegTree *son[2];
ValSegTree *root; IntSegTree() {
son[0] = son[1] = NULL;
root = new ValSegTree();
}
void Modify(int l,int r,int _l,int _r,int x) {
root->Modify(1,total,_l,_r);
if(l == r) return ;
int mid = (l + r) >> 1;
if(son[0] == NULL) son[0] = new IntSegTree();
if(son[1] == NULL) son[1] = new IntSegTree();
if(x <= mid) son[0]->Modify(l,mid,_l,_r,x);
else son[1]->Modify(mid + 1,r,_l,_r,x);
}
int Ask(int l,int r,int _l,int _r,int k) {
if(l == r) return l;
int mid = (l + r) >> 1;
if(son[0] == NULL) son[0] = new IntSegTree();
if(son[1] == NULL) son[1] = new IntSegTree();
int temp = son[1]->root->Ask(1,total,_l,_r);
if(k > temp) return son[0]->Ask(l,mid,_l,_r,k - temp);
else return son[1]->Ask(mid + 1,r,_l,_r,k);
}
}root; int main()
{
cin >> total >> asks;
for(int flag,x,y,z,i = 1;i <= asks; ++i) {
scanf("%d%d%d%d",&flag,&x,&y,&z);
if(flag == 1) root.Modify(1,total,x,y,z);
else printf("%d\n",root.Ask(1,total,x,y,z));
}
return 0;
}
BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)的更多相关文章
- [BZOJ 3110] [ZJOI 2013] K大数查询
Description 有 \(N\) 个位置,\(M\) 个操作.操作有两种,每次操作如果是: 1 a b c:表示在第 \(a\) 个位置到第 \(b\) 个位置,每个位置加入一个数 \(c\): ...
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
- 【34.14%】【BZOJ 3110】 [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MB Submit: 5375 Solved: 1835 [Submit][Status][Discuss] Descript ...
- 解题:ZJOI 2013 K大数查询
题面 树套树,权值线段树套序列线段树,每次在在权值线段树上的每棵子树上做区间加,查询的时候左右子树二分 本来想两个都动态开点的,这样能体现树套树在线的优越性.但是常数太大惹,所以外层直接固定建树了QA ...
- 【BZOJ 3110】 [Zjoi2013]K大数查询(整体二分)
[题目] Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到 ...
- 数据结构(树套树):ZJOI 2013 K大数查询
有几个点卡常数…… 发现若第一维为位置,第二维为大小,那么修改时第一维修改区间,查询时第一维查询区间,必须挂标记.而这种情况下标记很抽象,而且Push_down不是O(1)的,并不可行. 那要怎么做呢 ...
- BZOJ 3110:[Zjoi2013]K大数查询(整体二分)
http://www.lydsy.com/JudgeOnline/problem.php?id=3110 题意:-- 思路:其实和之前POJ那道题差不多,只不过是换成区间更新,而且是第k大不是第k小, ...
- [ZJOI 2013] K大数查询
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3110 [算法] 整体二分 + 线段树 时间复杂度 : O(NlogN ^ 2) [代 ...
- 【bzoj 3110】[Zjoi2013]K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
随机推荐
- hdu 2544
#include <iostream> #include <cstdio> #define INF 9999999 //#define INF 0x3f3f3f3 using ...
- HTML5 学习
1.<header> 标签定义文档的页眉(介绍信息) 标签是 HTML 5 中的新标签 <header> <h1>Welcome to my homepage< ...
- FTP链接mac
mac下一般用smb服务来进行远程文件访问,但要用FTP的话,高版本的mac os默认关掉了,可以用如下命令打开: sudo -s launchctl load -w /System/Library/ ...
- 如何在Eclipse中给main方法加参数
在main方法中有一个args参数,那么如何给args参数赋值呢? public class TestMain { public static void main(String[] args) { f ...
- Qt5遇到的问题
好久没用Qt了,今天又重新安装了一个,结果遇到不少问题 本机环境:VS2015,Qt5.7 装好后,就新建工程测试了一下,结果无法编译,提示 :-1: error: cannot open C:\Us ...
- PyQt5+python3的FindDialog
import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt, pyqtSignal class FindDialog(QD ...
- IntelliJ IDEA 12 创建Web项目 教程 超详细版
IntelliJ IDEA 12 新版本发布 第一时间去官网看了下 黑色的主题 很给力 大体使用了下 对于一开始就是用eclipse的童鞋们 估计很难从eclipse中走出来 当然 我也很艰难的走 ...
- mongo学习整理
mongo做为NOSQL家族中一员,被广泛使用以及应用到生产环境中,有其出色的性能.关系型数据库(RDBMS )在互联网中依然是不可替代的一部分,mongo基于NOSQL的特性,在程序中RDBMS不适 ...
- 类似a:hover的伪类的注解
a:link { font-size: 14pt; text-decoration: underline; color: blue; } /*设置a对象在未被访问前的样式表属性 .*/ a:hover ...
- 一句JS搞定只允许输入数字和字母
一句JS搞定输入框只允许用户输入数字和字母类型的内容,对象是input输入框,当然也可以其它对象,只不过input输入框用的频率非常高.一句代码,不信么?那就看下边代码: <INPUT clas ...