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 ...
随机推荐
- sendmail简单配置
yum -y install sendmail sendmail-cfservice sendmail startservice saslauthd statusif [ $? -ne 0 ];the ...
- [MicroPython]STM32F407开发板DIY声光控开关
1.实验目的 1. 学习在PC机系统中扩展简单I/O 接口的方法. 2. 进一步学习编制数据输出程序的设计方法. 3. 学习光敏模块的工作原理. 4. 学习声音的工作原理. 5. 学习F40 7Mic ...
- 环境部署(四):Linux下查看JDK安装路径
在安装好Git.JDK和jenkins之后,就需要在jenkins中进行对应的设置,比如在全局工具配置模块,需要写入JDK的安装路径. 这篇博客,介绍几种常见的在Linux中查看JDK路径的方法... ...
- javaweb 项目启动问题:Application Server was not connected before run configuration stop, reason: javax.manage
参考:https://blog.csdn.net/whm18322394724/article/details/80290187 换成本机的jre就行了(路径要正确,特别是项目迁移的时候有时候用环境变 ...
- MySQL root密码忘记,原来还有更优雅的解法!
一直以来,对于MySQL root密码的忘记,以为只有一种解法-skip-grant-tables. 问了下群里的大咖,第一反应也是skip-grant-tables.通过搜索引擎简单搜索了下,无论是 ...
- python 获取gearbest地址库代码
import requests import json # 用来去掉多余的字符,并格式化 def geshihua(str): s = None if "/**/_get_country(& ...
- Unix / Linux 线程的实质
线程与进程的比较 概述: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小 ...
- Vue父子传值
昨天创建完项目以后,今日首先使用项目来做一个简单的导航栏体会一下Vue的使用 1.项目的结构: 2.首先在Vheader.Vue中编辑代码: <template> <header c ...
- vue-lazyload简单使用
vue-lazyload简单使用 npm地址:https://www.npmjs.com/package/vue-lazyload github地址:https://github.com/hilong ...
- 将Myeclipse项目改成Eclipse项目
由于项目需求,需要将原来Myeclipse项目转移到Eclipse中去.搞了半天才搞出来,分享给大家,希望对大家有用. 首先导入一个从Myeclipse导出的项目 然后无法进行tomcat发布. 但是 ...