维护一个01串,一开始全部都是0
3种操作
1.把一个区间都变为1
2.把一个区间都变为0
3.把一个区间的所有数字翻转过来
每次操作完成之后询问区间最小的0的位置
l,r<=10^18
思路:先离散化(注意一定要把1也离散进去) 然后对每个区间[l,r] 把l-1,r+1也离散进去,最后维护一颗线段树(维护最大值和最小值)
#include <bits/stdc++.h> #define lson i<<1 #define rson i<<1|1 using namespace std; const int maxn = 5e6 + 5; typedef long long ll; struct Tree { int l, r; int mm, mx, lazy; }tree[maxn]; ll Hash[maxn], len; void pushup(int i) { tree[i].mx = max(tree[lson].mx, tree[rson].mx); tree[i].mm = min(tree[lson].mm, tree[rson].mm); } void check(int i) { if (tree[i].mx == 0) { tree[i].mm = tree[i].mx = 1; } else if (tree[i].mm == 1) { tree[i].mm = tree[i].mx = 0; } } void pushdown(int i) { if (tree[i].lazy == 0) return ; if (tree[i].lazy == 1) { tree[lson].mm = tree[lson].mx = 1; tree[rson].mm = tree[rson].mx = 1; tree[lson].lazy = 1; tree[rson].lazy = 1; } else if (tree[i].lazy == 2) { tree[lson].mm = tree[lson].mx = 0; tree[rson].mm = tree[rson].mx = 0; tree[lson].lazy = 2; tree[rson].lazy = 2; } else if (tree[i].lazy == 3) { if (tree[lson].lazy == 3) { check(lson); tree[lson].lazy = 0; } else if (tree[lson].lazy == 1) { check(lson); tree[lson].lazy = 2; } else if (tree[lson].lazy == 2) { check(lson); tree[lson].lazy = 1; } else if (tree[lson].lazy == 0) { check(lson); tree[lson].lazy = 3; } if (tree[rson].lazy == 3) { check(rson); tree[rson].lazy = 0; } else if (tree[rson].lazy == 1) { check(rson); tree[rson].lazy = 2; } else if (tree[rson].lazy == 2) { check(rson); tree[rson].lazy = 1; } else if (tree[rson].lazy == 0) { check(rson); tree[rson].lazy = 3; } } tree[i].lazy = 0; } void build(int i, int l, int r) { tree[i].l = l; tree[i].r = r; if (l >= r) return ; int mid = (l + r) / 2; build(lson, l, mid); build(rson, mid + 1, r); pushup(i); } struct node { ll opt, l, r; }q[maxn]; void updata(int i, int l, int r, int opt) { pushdown(i); int x = tree[i].l, y = tree[i].r; if (tree[i].l == l && tree[i].r == r) { if (opt == 1) { tree[i].mm = tree[i].mx = tree[i].lazy = 1; } else if (opt == 2) { tree[i].mm = tree[i].mx = 0; tree[i].lazy = 2; } else if (opt == 3) { if (tree[i].mx == 0) { tree[i].mm = tree[i].mx = 1; } else if (tree[i].mm == 1) { tree[i].mm = tree[i].mx = 0; } tree[i].lazy = 3; } return ; } int mid = (tree[i].l + tree[i].r) / 2; if (mid >= r) { updata(lson, l, r, opt); } else if (l > mid) { updata(rson, l, r, opt); } else { updata(lson, l, mid, opt); updata(rson, mid + 1, r, opt); } pushup(i); } ll query(int i) { pushdown(i); if (tree[i].l == tree[i].r) { return tree[i].l; } int mid = (tree[i].l + tree[i].r) / 2; if (tree[i * 2].mm == 0) { return query(lson); } else { return query(rson); } } /**/ int main() { int n; scanf("%d", &n); Hash[++len] = 1; for (int i = 1; i <= n; i++) { scanf("%lld%lld%lld", &q[i].opt, &q[i].l, &q[i].r); Hash[++len] = q[i].l; Hash[++len] = max(q[i].l - 1, 1LL); Hash[++len] = q[i].r; Hash[++len] = q[i].r + 1; } sort (Hash + 1, Hash + len + 1); len = unique(Hash + 1, Hash + len + 1) - Hash - 1; build(1, 1, len); for (int i = 1; i <= n; i++) { q[i].l = lower_bound(Hash + 1, Hash + len + 1, q[i].l) - Hash; q[i].r = lower_bound(Hash + 1, Hash + len + 1, q[i].r) - Hash; updata(1, q[i].l, q[i].r, q[i].opt); printf("%lld\n", Hash[query(1)]); } return 0; }