Tunnel Warfare(HDU1540+线段树+区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
题目:


题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的村庄相连接的城市数量。
思路:线段树+区间合并。
代码实现如下:
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = 1e8;
const int maxn = 5e4 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, q, x, t;
char op[];
int tack[maxn]; struct node {
int l, r, mx, ls, rs; //ls为左端最大连续区间,rs为右端最大连续区间,mx为区间内最大连续区间
}segtree[maxn*]; void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r;
segtree[i].mx = segtree[i].ls = segtree[i].rs = r - l + ;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} void update(int i, int pos, int x) {
if(segtree[i].l == segtree[i].r) {
if(x == ) segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //此处为修复操作
else segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //摧毁操作
return;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
update(i * , pos, x);
} else {
update(i * + , pos, x);
}
segtree[i].ls = segtree[i*].ls;
segtree[i].rs = segtree[i*+].rs;
segtree[i].mx = max(max(segtree[i*].mx, segtree[i*+].mx), segtree[*i].rs + segtree[i*+].ls);
if(segtree[i*].ls == segtree[i*].r - segtree[i*].l + ) { //如果左端全是连接的,那么ls还要右子树的ls
segtree[i].ls += segtree[i*+].ls;
}
if(segtree[i*+].rs == segtree[i*+].r - segtree[i*+].l + ) { //同理
segtree[i].rs += segtree[i*].rs;
}
} int query(int i, int pos) {
if(segtree[i].l == segtree[i].r || segtree[i].mx == segtree[i].r - segtree[i].l + || segtree[i].mx == ) {
return segtree[i].mx;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
if(pos >= segtree[*i].r - segtree[i*].rs + ) { //如果pos与右边连接,那么还需要跑另一棵子树
return query(i * , pos) + query(i * + , mid + );
} else {
return query(i * , pos);
}
} else {
if(pos <= segtree[i * + ].l + segtree[i*+].ls - ) { //同理
return query(i * + , pos) + query(i * , mid);
} else {
return query(i * + , pos);
}
}
} int main() {
//FIN;
while(~scanf("%d%d", &n, &q)) {
build(, , n);
t = ;
while(q--) {
scanf("%s", op);
if(op[] == 'D') {
scanf("%d", &x);
tack[++t] = x;
update(, x, );
} else if(op[] == 'R') {
if(t > ) {
x = tack[t--];
update(, x, );
}
} else {
scanf("%d", &x);
printf("%d\n", query(, x));
}
}
}
return ;
}
Tunnel Warfare(HDU1540+线段树+区间合并)的更多相关文章
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
Tunnel Warfare Time Limit: 4000/2000 MS ...
- HDU - 1540 Tunnel Warfare(线段树区间合并)
https://cn.vjudge.net/problem/HDU-1540 题意 D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 分析 线段树的区间内,我 ...
- HDU 1540 Tunnel Warfare(线段树+区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目大意:抗日战争期间进行地道战,存在n个村庄用地道连接,输入D表示破坏某个村庄(摧毁与其相连的地道, 包 ...
- hdu 1540 Tunnel Warfare (线段树 区间合并)
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- HDU--1540 Tunnel Warfare(线段树区间更新)
题目链接:1540 Tunnel Warfare 以为单组输入 这个题多组输入 结构体记录每个区间左边和右边的连续区间 ms记录最大 在查询操作时: 1.这个点即将查询到右区间 看这个点 x 是否存在 ...
- HDU1540 Tunnel Warfare(线段树区间维护&求最长连续区间)题解
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- hdu1540-Tunnel Warfare (线段树区间合并)
题意:n个村庄,有三种操作,D x 破坏位置为x的村庄,R 修复上一次被破坏的村庄,Q x 输出含有x村庄的连续村庄的最大个数.线段树搞之,区间合并. ls[maxn]为当前节点左面的连续区间,rs[ ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
随机推荐
- LintCode-366.斐波纳契数
斐波纳契数列 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是:0, 1, 1 ...
- LintCode-381.螺旋矩阵 II
螺旋矩阵 II 给你一个数n生成一个包含1-n^2的螺旋形矩阵 样例 n = 3 矩阵为 [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 标 ...
- matlab怎么选取excel的特定列构成数组
例如:
- 内存交换空间(swap)的构建
一.使用物理分区构建swap 1.先进行分区的行为. [root@iZ255cppmtxZ ~]# fdisk /dev/xvdb Welcome to fdisk (util-linux ). Ch ...
- 线程同步(使用了synchronized)和线程通讯(使用了wait,notify)
线程同步 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题. 实现同步机制有两个方法:1.同 ...
- ASP.Net MVC+Ibaties架构
1.配置Ibaties首先在DLL引用中添加Ibaties相关引用:IBatisNet.Common.dll;IBatisNet.Common.Logging.Log4Net.dll;IBatisNe ...
- [洛谷P4248][AHOI2013]差异
题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...
- React获取组件实例
1. 直接new Component() 组件本身也是class,可以new,这样的组件实例意义不大 componentInstance = new Component(); 2. ReactDOM. ...
- java 解析http返回xml数据
//post 请求 private static String sendPost(String url, String urlParameters) throws Exception { URL ob ...
- 2017-7-18-每日博客-关于Linux下的history的常用命令.doc
History history命令可以用来显示曾执行过的命令.执行过的命令默认存储在HOME目录中的.bash_history文件中,可以通过查看该文件来获取执行命令的历史记录.需要注意的是.bash ...