• 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 }
  • 相关阅读:
    Pytest(2)使用和调用方法
    lnmp一键搭建环境 running
    cd / 、cd~、cd .和cd..区别 running
    php算法之冒泡排序 running
    linux系统安装 running
    webpack之urlloader running
    Unix系列shell程序编写(下)
    目标文件格式分析工具: ar,nm,objdump,objcopy,readelf
    Unix系列shell程序编写(上)
    在vmware下安装的linux系统上添加eth1
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9366584.html
Copyright © 2020-2023  润新知