hdu 1540 Tunnel Warfare

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题目大意:给你一排连续的点,你可以进行下面三种操作:

1、删除一个点

2、询问和一个点所在段的长度(如果该点已删除,长度为0)

3、恢复上一个删除的点

线段树计算连续区间,结点保存该段左连续长度lm,和右连续长度rm

  1 /*
  2  * Problem: hdu 1540 Tunnel Warfare
  3  * Author:  SHJWUDP
  4  * Created Time:  2015/3/28 星期六 13:10:49
  5  * File Name: 233.cpp
  6  * State: Accepted
  7  * Memo: 线段树
  8  */
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13 
 14 using namespace std;
 15 
 16 const int MaxA=5e4+7;
 17 
 18 struct SegmentTree {
 19 //这个结构可以求最大连续区间,只需要加上一个变量保存当前节点下最大连续区间
 20     struct Node {    
 21         int lm, rm;
 22         Node(){}
 23         Node(int l, int r):lm(l), rm(r){}
 24     } *c;
 25     int n;
 26     int p, sign;
 27 
 28     SegmentTree(int n):n(n) {
 29         c=new Node[(n+7)<<2];
 30         build(1, n, 1);
 31     }
 32     ~SegmentTree() {
 33         delete c;
 34     }
 35 #define INIT Node& u=c[rt]; Node& ls=c[rt<<1]; Node& rs=c[rt<<1|1];
 36 #define lson l, m, rt<<1
 37 #define rson m+1, r, rt<<1|1
 38 
 39     void pushUp(int l, int m, int r, int rt) {
 40         INIT;
 41         u=Node(ls.lm, rs.rm);
 42         if(m-l+1==ls.lm) u.lm+=rs.lm;
 43         if(r-m==rs.rm) u.rm+=ls.rm;
 44     }
 45 
 46     void build(int l, int r, int rt) {
 47         if(l==r) {
 48             c[rt]=Node(1, 1);
 49         } else {
 50             int m=(l+r)>>1;
 51             build(lson);
 52             build(rson);
 53             pushUp(l, m, r, rt);
 54         }
 55     }
 56 
 57     void doUpdate(int l, int r, int rt) {
 58         if(l==r) {
 59             c[rt]=sign?Node(1, 1):Node(0, 0);
 60         } else {
 61             int m=(l+r)>>1;
 62             if(p<=m) doUpdate(lson);
 63             else doUpdate(rson);
 64             pushUp(l, m, r, rt);
 65         }
 66     }
 67 
 68     void update(int p, int sign) {
 69         this->p=p; this->sign=sign;
 70         doUpdate(1, n, 1);
 71     }
 72 
 73     int doQuery(int l, int r, int rt) {
 74         INIT;
 75         if(p-l<u.lm || r-p<u.rm) {
 76             return p-l<u.lm?u.lm:u.rm;
 77         } else if(l==r) return 0;
 78         else {
 79             int m=(l+r)>>1;
 80             int res=0;
 81             if(p<=m) res+=doQuery(lson)+(m-p+1<=ls.rm?rs.lm:0);
 82             else res+=doQuery(rson)+(p-m<=rs.lm?ls.rm:0);
 83             return res;
 84         }
 85     }
 86 
 87     int query(int p) {
 88         this->p=p;
 89         return doQuery(1, n, 1);
 90     }
 91 #undef INIT
 92 #undef lson
 93 #undef rson
 94 };
 95 
 96 int n, m;
 97 int stk[MaxA], top;
 98 int main() {
 99 #ifndef ONLINE_JUDGE
100     freopen("in", "r", stdin);
101     //freopen("out", "w", stdout);
102 #endif
103     while(~scanf("%d%d", &n, &m)) {
104         SegmentTree st(n);
105         top=0;
106         while(m--) {
107             char op[2];
108             int x;
109             scanf("%s", op);
110             switch(op[0]) {
111             case 'D': 
112                 scanf("%d", &x);
113                 st.update(stk[++top]=x, 0);
114                 break;
115             case 'Q': 
116                 scanf("%d", &x);
117                 printf("%d
", st.query(x));
118                 break;
119             case 'R': 
120                 st.update(stk[top--], 1);
121                 break;
122             }
123         }
124     }
125     return 0;
126 }
hdu 1540
原文地址:https://www.cnblogs.com/shjwudp/p/4386808.html