题目链接: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+线段树+区间合并)的更多相关文章

  1. hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

    Tunnel Warfare                                                             Time Limit: 4000/2000 MS ...

  2. HDU - 1540 Tunnel Warfare(线段树区间合并)

    https://cn.vjudge.net/problem/HDU-1540 题意 D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 分析 线段树的区间内,我 ...

  3. HDU 1540 Tunnel Warfare(线段树+区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目大意:抗日战争期间进行地道战,存在n个村庄用地道连接,输入D表示破坏某个村庄(摧毁与其相连的地道, 包 ...

  4. hdu 1540 Tunnel Warfare (线段树 区间合并)

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  5. HDU--1540 Tunnel Warfare(线段树区间更新)

    题目链接:1540 Tunnel Warfare 以为单组输入 这个题多组输入 结构体记录每个区间左边和右边的连续区间 ms记录最大 在查询操作时: 1.这个点即将查询到右区间 看这个点 x 是否存在 ...

  6. HDU1540 Tunnel Warfare(线段树区间维护&求最长连续区间)题解

    Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  7. hdu1540-Tunnel Warfare (线段树区间合并)

    题意:n个村庄,有三种操作,D x 破坏位置为x的村庄,R 修复上一次被破坏的村庄,Q x 输出含有x村庄的连续村庄的最大个数.线段树搞之,区间合并. ls[maxn]为当前节点左面的连续区间,rs[ ...

  8. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  9. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

随机推荐

  1. TCP系列02—连接管理—1、三次握手与四次挥手

    一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...

  2. 3dContactPointAnnotationTool开发日志(十六)

      调了一上午才发现是把下面这个函数: private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector ...

  3. python爬虫 --- 简书评论

    某些网站的一些数据是通过js加载的 ,所以爬取下来的数据拿不到, 找到评论的地址 .进行请求获取评论数据 #coding=utf-8 import json import requests def r ...

  4. Maximum execution time of 30 seconds exceeded解决办法

    Maximum execution time of 30 seconds exceeded,今天把这个错误的解决方案总结一下: 简单总结一下解决办法: 报错一:内存超限,具体报错语句忘了,简单说一下解 ...

  5. ManagementClass("Win32_Share")之共享目录

    public class ShareFolder { private static readonly Dictionary<uint, string> ReturnDetails = ne ...

  6. 从一个ListBox中的元素点击导入另一个ListBox元素中

    先看效果图:

  7. 【hdu4734】F(x) 数位dp

    题目描述 对于一个非负整数 $x=​​\overline{a_na_{n-1}...a_2a_1}$ ,设 $F(x)=a_n·2^{n-1}+a_{n-1}·2^{n-2}+...+a_2·2^1+ ...

  8. [bzoj4398] 福慧双修 最短路 二进制分组

    ---题面--- 题解: 考场上看的这道题,,,当时70分算法打挂了,今天才知道这个也是原题.... 首先,对于不跟1相邻的边,肯定不会经过两次,因为经过两次就回来了,除了增加路径长度之外没有任何意义 ...

  9. 洛谷3800:Power收集——题解

    https://www.luogu.org/problemnew/show/P3800 可以把游戏界面理解成一个N行M列的棋盘,有K个格子上有P点,其价值为val(i,j) 初始灵梦可以选择在第一行的 ...

  10. CC DGCD:Dynamic GCD——题解

    https://vjudge.net/problem/CodeChef-DGCD https://www.codechef.com/problems/DGCD 题目大意: 给一颗带点权的树,两个操作: ...