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个位 ...
随机推荐
- HTML中常用鼠标样式
语法:cursor : auto | all-scroll | col-resize| crosshair | default | hand | move | help | no-drop | not ...
- 静默安装ORACLE【weber出品必属精品】
安装配置系统环境安装linux ,所有服务都不选择,只是选择安装开发工具,不要安装防火墙(当然也可以在后面关闭) 打开终端,执行如下命令,检查安装包,没有的都要安装 make, glibc, liba ...
- C# 操作电脑 关机 重启 注销 休止 休眠
// 关机 强制电脑10秒之内关机 //System.Diagnostics.Process.Start("shutdown", "-s -f -t 10"); ...
- ajaxfileupload
} } setTimeout( }, s. ...
- 1.Tomcat配置
1.启动 解压缩安装包后,点击startup.bat,保持控制台窗口开启 浏览器中输入http://localhost:8080 后看到启动界面则表示启动成功 点击shutdown.bat则关闭Tom ...
- tkinter之文件对话框
from tkinter import * from tkinter.filedialog import * filetype = [('Python Files', '*.py *.pyw'), ( ...
- 一个PHP常用表单验证类(基于正则)
一个基于正则表达式的PHP常用表单验证类,作者:欣然随风.这个表单判断类的功能有:验证是否为指定长度的字母/数字组合.验证是否为指定长度汉字.身 份证号码验证.是否是指定长度的数字.验证邮件地址.电话 ...
- C#泛型理解(转)
[译]C# 理解泛型 PDF 浏览:http://www.tracefact.net/document/generics-in-csharp.pdf源码下载:http://www.tracefact ...
- 汉诺塔 Hanoi Tower
电影<猩球崛起>刚开始的时候,年轻的Caesar在玩一种很有意思的游戏,就是汉诺塔...... 汉诺塔源自一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度 ...
- asp.net core VS goang web[修正篇]
先前写过一篇文章:http://www.cnblogs.com/gengzhe/p/5557789.html,也是asp.net core和golang web的对比,热心的园友提出了几点问题,如下: ...