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个位 ...
随机推荐
- bootstrap初探
bootstrap资源 http://getbootstrap.com http://github.com/twbs http://www.bootcss.com bootstrap栅格系统 容器:流 ...
- CSS元素分类及区别
元素是文档结构的基础,在CSS中,每个元素生成了一个包含了元素内容的框(box,也译为“盒子”).但是不同的元素显示的方式会有所不同,例如<div>和<span>就不同,而&l ...
- C# 连接SQL数据库
感觉很有必要总结一下 一:C# 连接SQL数据库 Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;P ...
- HTML5 microdata
schema.org 测试地址 http://www.google.com/webmasters/tools/richsnippets
- Cacti添加IO模板并监控磁盘IO
1.下载Cacti_Net-SNMP_DevIO_v3.1.zip 下载Cacti_Net-SNMP_DevIO_v3.1.zip,解压并上传net-snmp_devio.xml到/resource/ ...
- 武汉科技大学ACM :1004: 华科版C语言程序设计教程(第二版)课后习题3.7
Problem Description 输入无符号短整数k[hex.]和p[oct.],将k的高字节作为结果的低字节,p的高字节作为结果的高字节组成一个新的整数. Input k[hex.]和p[oc ...
- tribonacci
Everybody knows Fibonacci numbers, now we are talking about the Tribonacci numbers: T[0] = T[1] = T[ ...
- [转]《深度探索C++对象模型》读书笔记[二]
3.3 Data Member的存取1. 不管什么情况,每一个static data member只有一个实体,放在程序的data segment之中,每次程序取用static member,不管 ...
- js console.log 打印 对像 数组 详解
console.log是什么东西,其实就是一个打印js数组和对像的函数而已,就像是php的print_r,var_dump.console.log这个函数本身没什么好说的,这篇博客告诉大家怎么去用这个 ...
- 【行为型】Command模式
命令模式是指将用户的请求封装成(命令)对象,从而可将用户不同的请求进行参数化.对这些请求排序或记录请求日志.以及支持回滚恢复操作.记得以前刚开始使用Photoshop时,就发现它的操作历史记录面板特别 ...