维护一个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;
}