Hdu 1540 【线段树--区间合并】.cpp

题意:
  有3个操作
    D a 毁坏某一个点a
    R 修复上一次破坏的点
    Q a 问a点附近连续的点有几个

思路:
  区间合并类的线段树
    结构体表示 {
      l:节点的左界限
      r:节点的右界限
      ll:左起连续的点数
      rr:右起连续的点数
      mm:整个范围内连续最长的点数
    }

Tips:
   主要是更新那一块要考虑父节点可能是由左右节点边界合并的
   询问那一块要考虑是否可以和兄弟节点合并

 

Code:

 1 #include <stdio.h>

 2 #include <cstring>

 3 #include <algorithm>

 4 using namespace std;

 5 

 6 const int MAXN = 50010;

 7 

 8 struct Node

 9 {

10     int l, r;

11     int ll, rr, mm;

12 }node[MAXN<<2];

13 

14 void build(int rt, int l, int r)

15 {

16     node[rt].l = l, node[rt].r = r;

17     node[rt].ll = node[rt].rr = node[rt].mm = r-l+1;

18     if (l == r) return;

19     int mid = (r+l)>>1;

20     build(rt<<1, l, mid);

21     build(rt<<1|1, mid+1, r);

22 }

23 

24 void modify(int rt, int p, int w)

25 {

26     if (node[rt].l == node[rt].r) {

27         if (w == 1) node[rt].ll = node[rt].rr = node[rt].mm = 1;

28         else node[rt].ll = node[rt].rr = node[rt].mm = 0;

29         return;

30     }

31     int mid = (node[rt].l + node[rt].r)>>1;

32     if (p <= mid) modify(rt<<1, p, w);

33     else modify(rt<<1|1, p, w);

34 

35     node[rt].ll = node[rt<<1].ll, node[rt].rr = node[rt<<1|1].rr;

36     if (node[rt<<1].rr == node[rt<<1].r-node[rt<<1].l+1) {

37         node[rt].ll = node[rt<<1].rr + node[rt<<1|1].ll;

38     }

39     if (node[rt<<1|1].rr == node[rt<<1|1].r - node[rt<<1|1].l+1) {

40         node[rt].rr = node[rt<<1|1].rr+node[rt<<1].rr;

41     }

42     node[rt].mm = max(node[rt<<1].mm, node[rt<<1|1].mm);

43     node[rt].mm = max(node[rt].mm, node[rt<<1].rr+node[rt<<1|1].ll);

44 }

45 

46 int query(int rt, int p)

47 {

48     int ans;

49     if (node[rt].l == node[rt].r || node[rt].mm == 0 || node[rt].mm == node[rt].r-node[rt].l+1) {

50         return node[rt].mm;

51     }

52     int mid = (node[rt].l+node[rt].r)>>1;

53     if (p <= mid) {

54         ans = query(rt<<1, p);

55         if (p >= node[rt<<1].r-node[rt<<1].rr+1) //ans += node[rt<<1|1].ll;

56             ans += query(rt<<1|1, mid+1);

57     } else {

58         ans = query(rt<<1|1, p);

59         if (p <= node[rt<<1|1].l+node[rt<<1|1].ll-1) //ans += node[rt<<1].rr;

60             ans += query(rt<<1, mid);

61     }

62     return ans;

63 }

64 

65 int main()

66 {

67    // freopen("in.txt", "r", stdin);

68     int n, m, tmp;

69     int sta[MAXN], tp;

70     char ord[3];

71     while (~scanf("%d %d", &n, &m)) {

72         tp = 0;

73         build(1, 1, n);

74         while (m--) {

75             scanf("%s", ord);

76             if (ord[0] == 'D') {

77                 scanf("%d", &tmp);

78                 sta[tp++] = tmp;

79                 modify(1, tmp, 0);

80             } else if (ord[0] == 'Q') {

81                 scanf("%d", &tmp);

82                 printf("%d\n", query(1, tmp));

83             } else {

84                 tp--;

85                 modify(1, sta[tp], 1);

86             }

87         }

88     }

89     return 0;

90 }
View Code

 


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

你可能感兴趣的:(HDU)