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 ...
随机推荐
- .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中
不知你是否见过 try { } finally { } 代码中,try 块留空,而只往 finally 中写代码的情况呢?这种写法有其特殊的目的. 本文就来说说这种不一样的写法. 你可以点开这个链接查 ...
- Oja’s rule
目录 Oja's rule 背景 Hebbian learning 主要的一些理论 论文里面一些主要的假设 引理1 引理2 引理3 定理1 LEMMA 3(ALL) 引理 4 定理 2 定理 3(关于 ...
- PHP的内存回收(GC)
php官方对gc的介绍:http://php.net/manual/zh/features.gc.php
- Linux查看硬件等基本参数
http://www.cnblogs.com/xd502djj/archive/2011/02/28/1967350.html
- MySQL 5.7 Reference Manual :: 4.5.4 mysqldump & mysql — Database Backup & Restore Program
MySQL :: MySQL 5.7 Reference Manual :: 4.5.4 mysqldump — A Database Backup Programhttps://dev.mysql. ...
- CentOS下配置SS5(SOCKS5)代理服务器
方案:使用开源的SS5( Socks Server 5 ) 官网:http://ss5.sourceforge.net/ (点击左侧的Software在右侧的Server处进入下载地址) CentOs ...
- ios点击输入框,界面放大解决方案
当我们编写的input宽度没有占满屏幕宽度,而且又没有申明meta,就会出现点击输入框,界面放大这个问题. 下面我直接给出解决方案: <meta name="viewport" ...
- C\C++学习笔记 1
C++记录1 C的头文件为math.h C++的为 cmath using编译指令 namespace 区分不同产品的函数.Mics::cout Linux::cout cout << 即 ...
- Composer对于第三方包的自动加载
Composer提供了四种方式的支持,分别是 PSR-0和PSR-4的自动加载(我的一篇文章也有介绍过它们),生成class-map,和直接包含files的方式. PSR-4是composer推荐使用 ...
- [转帖]SAP一句话入门:Production Planning
SAP一句话入门:Production Planning http://blog.vsharing.com/MilesForce/A617692.html SAP是庞大的,模块是多多的,功能是强大的, ...