Tunnel Warfare(线段树取连续区间)
emmmmmmmm我菜爆了
思路来自:https://blog.csdn.net/chudongfang2015/article/details/52133243
线段树最难的应该就是要维护什么东西
这道题刚开始1~n都是连通的
D x 即破坏x这个地方
Q x 即查询包含x的连续区间有多长
R 即修复最后一次D的x
博主给了一个非常好的思路
线段树维护两个值,该区间内被破坏的最大的点,以及最小的那个点
如 1,2,...,,6 破坏了 2 ,4,5 那么该区间里的pmax = 5,pmin = 2
若要查询3 则取3右边的pmin 减去 3左边的pmax 再减1
3右的pmin = 4, 3左的pmax = 2 即为 4 - 2 - 1 = 1
未被破坏的点或者区间的pmax pmin分别设为0,n + 1
这样就能query的值能直接用来计算
比如1,2,3,4,5均为被破坏
则pmin - pmax - 1 = n = 5
特殊情况就为查询的x自身被破坏了
pmin = pmax = x 这样打印的结果是-1,所以打印的时候取一下pmin-pmax-1和0的最大值就好了
(orz多转换思路,试试各种值的维护)
#include <cstdio>
#include <algorithm>
#define lp p<<1
#define rp p<<1|1
using namespace std;
const int maxn = 5e4 + ;
int pmin[maxn<<], pmax[maxn<<];
int des[maxn], n; void build(int p, int l, int r) {
if (l == r) {
pmin[p] = n + ;
pmax[p] = ;
return;
}
int mid = l + r >> ;
build(lp, l, mid);
build(rp, mid + , r);
pmax[p] = max(pmax[lp], pmax[rp]);
pmin[p] = min(pmin[lp], pmin[rp]);
}
void update(int p, int l, int r, int pos, int num1, int num2) {
if (l == r) {
pmax[p] = num1;
pmin[p] = num2;
return;
}
int mid = l + r >> ;
if (pos <= mid) {
update(lp, l, mid, pos, num1, num2);
} else {
update(rp, mid + , r, pos, num1, num2);
}
pmax[p] = max(pmax[lp], pmax[rp]);
pmin[p] = min(pmin[lp], pmin[rp]);
}
int query_min(int p, int l, int r, int x, int y) {
if (x <= l && y >= r) return pmin[p];
int mid = l + r >> ;
int res = 0x3f3f3f3f;
if (x <= mid) res = min(res, query_min(lp, l, mid, x, y));
if (y > mid) res = min(res, query_min(rp, mid + , r, x, y));
return res;
}
int query_max(int p, int l, int r, int x, int y) {
if (x <= l && y >= r) return pmax[p];
int mid = l + r >> ;
int res = ;
if (x <= mid) res = max(res, query_max(lp, l, mid, x, y));
if (y > mid) res = max(res, query_max(rp, mid + , r, x, y));
return res;
} int main() {
int m;
while (~scanf("%d%d", &n, &m)) {
int last = ;
build(, , n);
while (m--) {
char opt[];
scanf("%s", opt);
if (opt[] == 'D') {
int p;
scanf("%d", &p);
update(, , n, p, p, p);
des[++last] = p;
} else if (opt[] == 'R') {
update(, , n, des[last--], , n + );
} else {
int q;
scanf("%d", &q);
int ans1 = query_max(, , n, , q), ans2 = query_min(, , n, q, n);
printf("%d\n", ans2 - ans1 - > ? ans2 - ans1 - : );
}
}
}
return ;
}
对博主的代码简化了一下下(
Tunnel Warfare(线段树取连续区间)的更多相关文章
- HDU 1540 Tunnel Warfare 线段树区间合并
Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...
- hdu 1540 Tunnel Warfare(线段树区间统计)
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- HDU 1540 Tunnel Warfare (线段树)
Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...
- Tunnel Warfare 线段树 区间合并|最大最小值
B - Tunnel WarfareHDU - 1540 这个有两种方法,一个是区间和并,这个我个人感觉异常恶心 第二种方法就是找最大最小值 kuangbin——线段树专题 H - Tunnel Wa ...
- hdu1540 Tunnel Warfare 线段树/树状数组
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
Tunnel Warfare Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 1540 Tunnel Warfare (线段树或set水过)
题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 析:首先可以用set水过,set用来记录每个被破坏的村庄,然后查找时,只要查找左右两个端点好. 用线段 ...
- HDU 1540 Tunnel Warfare (线段树)
题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄.其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最 ...
- HDU1540 Tunnel Warfare —— 线段树 区间合并
题目链接:https://vjudge.net/problem/HDU-1540 uring the War of Resistance Against Japan, tunnel warfare w ...
随机推荐
- Python分析微信好友性别比例和省份城市分布比例
如需转发请注明:小婷儿的博客:https://www.cnblogs.com/xxtalhr/p/10642241.html 一.安装模块 pip install itchat pip install ...
- kali 源
#阿里云 deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib deb-src http://mirrors.al ...
- keras神经网络三个例子
keras构造神经网络,非常之方便!以后就它了.本文给出了三个例子,都是普通的神经网络 例一.离散输出,单标签.多分类 例二.图像识别,单标签.多分类.没有用到卷积神经网络(CNN) 例三.时序预测, ...
- Elasticsearch 思维导图集锦(持续更新...)
目录 引言 思维导图 全文搜索 Elastic 基础 Query DSL Multi Match Query 系列文章列表 参考 引言 本文主要是对 elasticsearch 的一些知识点使用思维导 ...
- handsontable 的核心方法
原文地址:http://blog.csdn.net/mafan121/article/details/46122577 1.为handsontable添加钩子方法 addHook(key,callba ...
- VMware(威睿)后端开发笔试题总结
1. Linux中查看系统的发行版本信息 的命令? cat/etc/issue 和 lsb_release 2. linux 挂载一个共享文件夹: mount -t cifc ...
- BZOJ1283 序列 网络流区间覆盖模型
就是区间覆盖模型的费用流版. 区间覆盖模型
- Sparse Principal Component Analysis via Rotation and Truncation
目录 对以往一些SPCA算法复杂度的总结 Notation 论文概述 原始问题 问题的变种 算法 固定\(X\),计算\(R\) 固定\(R\),求解\(X\) (\(Z =VR^{\mathrm{T ...
- c++之sizeof的用法
在此温习一下c语言中sizeof的用法以及c++11.0的标准中,关于初始化的新方式,先上代码: # include "iostream" # include "stri ...
- Rikka with Subset HDU - 6092 (DP+组合数)
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...