@Acqua
2019-01-17T12:11:43.000000Z
字数 1432
阅读 997
线段树
给定一个长度为、初始全为1的序列和个操作:
1. :将变为0
2. :将上一个被变为0的元素恢复为1
3. :求所在的连续1区间长度
区间合并,但是在查询上遇到了些许困难。
- 此次查错耗时过长,需要更新差错算法。
- 线段树区间合并基本掌握。
// La Lune#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define il u << 1#define el u << 1 | 1#define lson il, l, mid#define rson el, mid + 1, r#define root 1, 1, n#define morb int u, int l, int rusing namespace std;const int N = 5e4 + 5;int lu[N << 2], un[N << 2], ne[N << 2], lune[N];void pushup(int u, int m){lu[u] = lu[il];ne[u] = ne[el];if(lu[il] == (m - (m >> 1)))lu[u] += lu[el];if(ne[el] == (m >> 1))ne[u] += ne[il];un[u] = max(ne[il] + lu[el], max(un[il], un[el]));}void build(morb){lu[u] = un[u] = ne[u] = r - l + 1;if(l == r)return;int mid = l + r >> 1;build(lson);build(rson);}void update(morb, int x, int c){if(l == r && l == x){lu[u] = un[u] = ne[u] = c;return;}int mid = l + r >> 1;if(x <= mid)update(lson, x, c);elseupdate(rson, x, c);pushup(u, r - l + 1);}int query(morb, int x){if(l == r || un[u] == 0 || un[u] == r - l + 1)return un[u];int mid = l + r >> 1;if(x <= mid){if(x >= mid - ne[il] + 1)return query(lson, x) + query(rson, mid + 1);elsereturn query(lson, x);}else{if(x <= mid + 1 + lu[el] - 1)return query(lson, mid) + query(rson, x);elsereturn query(rson, x);}}int main(){int n, q;while(~scanf("%d %d", &n, &q)){int t = 0;build(root);while(q--){char c; int pos;scanf("\n%c ", &c);if(c == 'D'){scanf("%d", &pos);update(root, pos, 0);lune[++ t] = pos;}if(c == 'R'){if(t > 0)update(root, lune[t--], 1);}if(c == 'Q'){scanf("%d", &pos);printf("%d\n", query(root, pos));}}}return 0;}