Tunnel Warfare(HDU1540+线段树+区间合并)

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

题目:

题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的村庄相连接的城市数量。

思路:线段树+区间合并。

代码实现如下:

  1 #include <set>
  2 #include <map>
  3 #include <queue>
  4 #include <stack>
  5 #include <cmath>
  6 #include <bitset>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 
 16 typedef long long ll;
 17 typedef unsigned long long ull;
 18 
 19 #define lson i<<1,l,mid
 20 #define rson i<<1|1,mid+1,r
 21 #define bug printf("*********
");
 22 #define FIN freopen("D://code//in.txt", "r", stdin);
 23 #define debug(x) cout<<"["<<x<<"]" <<endl;
 24 #define IO ios::sync_with_stdio(false),cin.tie(0);
 25 
 26 const double eps = 1e-8;
 27 const int mod = 1e8;
 28 const int maxn = 5e4 + 7;
 29 const double pi = acos(-1);
 30 const int inf = 0x3f3f3f3f;
 31 const ll INF = 0x3f3f3f3f3f3f3f3f;
 32 
 33 inline int read() {//读入挂
 34     int ret = 0, c, f = 1;
 35     for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
 36     if(c == '-') f = -1, c = getchar();
 37     for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
 38     if(f < 0) ret = -ret;
 39     return ret;
 40 }
 41 
 42 int n, q, x, t;
 43 char op[5];
 44 int tack[maxn];
 45 
 46 struct  node {
 47     int l, r, mx, ls, rs; //ls为左端最大连续区间,rs为右端最大连续区间,mx为区间内最大连续区间
 48 }segtree[maxn*4];
 49 
 50 void build(int i, int l, int r) {
 51     segtree[i].l = l, segtree[i].r = r;
 52     segtree[i].mx = segtree[i].ls = segtree[i].rs = r - l + 1;
 53     if(l == r) return;
 54     int mid = (l + r) >> 1;
 55     build(lson);
 56     build(rson);
 57 }
 58 
 59 void update(int i, int pos, int x) {
 60     if(segtree[i].l == segtree[i].r) {
 61         if(x == 1) segtree[i].mx = segtree[i].ls = segtree[i].rs = 1; //此处为修复操作
 62         else segtree[i].mx = segtree[i].ls = segtree[i].rs = 0; //摧毁操作
 63         return;
 64     }
 65     int mid = (segtree[i].l + segtree[i].r) >> 1;
 66     if(pos <= mid) {
 67         update(i * 2, pos, x);
 68     } else {
 69         update(i * 2 + 1, pos, x);
 70     }
 71     segtree[i].ls = segtree[i*2].ls;
 72     segtree[i].rs = segtree[i*2+1].rs;
 73     segtree[i].mx = max(max(segtree[i*2].mx, segtree[i*2+1].mx), segtree[2*i].rs + segtree[i*2+1].ls);
 74     if(segtree[i*2].ls == segtree[i*2].r - segtree[i*2].l + 1) { //如果左端全是连接的,那么ls还要右子树的ls
 75         segtree[i].ls += segtree[i*2+1].ls;
 76     }
 77     if(segtree[i*2+1].rs == segtree[i*2+1].r - segtree[i*2+1].l + 1) { //同理
 78         segtree[i].rs += segtree[i*2].rs;
 79     }
 80 }
 81 
 82 int query(int i, int pos) {
 83     if(segtree[i].l == segtree[i].r || segtree[i].mx == segtree[i].r - segtree[i].l + 1 || segtree[i].mx == 0) {
 84         return segtree[i].mx;
 85     }
 86     int mid = (segtree[i].l + segtree[i].r) >> 1;
 87     if(pos <= mid) {
 88         if(pos >= segtree[2*i].r - segtree[i*2].rs + 1) { //如果pos与右边连接,那么还需要跑另一棵子树
 89             return query(i * 2, pos) + query(i * 2 + 1, mid + 1);
 90         } else {
 91             return query(i * 2, pos);
 92         }
 93     } else {
 94         if(pos <= segtree[i * 2 + 1].l + segtree[i*2+1].ls - 1) { //同理
 95             return query(i * 2 + 1, pos) + query(i * 2, mid);
 96         } else {
 97             return query(i * 2 + 1, pos);
 98         }
 99     }
100 }
101 
102 int main() {
103     //FIN;
104     while(~scanf("%d%d", &n, &q)) {
105         build(1, 1, n);
106         t = 0;
107         while(q--) {
108             scanf("%s", op);
109             if(op[0] == 'D') {
110                 scanf("%d", &x);
111                 tack[++t] = x;
112                 update(1, x, 2);
113             } else if(op[0] == 'R') {
114                 if(t > 0) {
115                     x = tack[t--];
116                     update(1, x, 1);
117                 }
118             } else {
119                 scanf("%d", &x);
120                 printf("%d
", query(1, x));
121             }
122         }
123     }
124     return 0;
125 }
原文地址:https://www.cnblogs.com/Dillonh/p/9366584.html