题意:
有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 }