1. 程式人生 > >CF817F MEX Queries

CF817F MEX Queries

開始 blog esp adjust name 離散化 n) lin namespace

題意

維護一個\(01\)串,一開始全部都是\(0\)
\(3\)種操作
\(1.\)把一個區間都變為\(1\)
\(2.\)把一個區間都變為\(0\)
\(3.\)把一個區間的所有數字翻轉過來
每次操作完成之後詢問區間最小的\(0\)的位置
\(l,r<=10^{18}\)

Sol

直接上線段樹,如果這個區間左邊是滿的就去右邊,否則去左邊
動態開點,加上\(lazy\)
但這樣會爆空間

所以把區間離散化
註意要離散\(1\)\(l\)\(r\)\(l+1\)\(r+1\)
這些都可能會出現答案

# include <bits/stdc++.h>
# define RG register
# define IL inline # define Fill(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(4e5 + 5); IL ll Input(){ RG ll x = 0, z = 1; RG char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0'
&& c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); return x * z; } int n, len, opt[_]; ll ql[_], qr[_], o[_]; struct Segment{ int sum, rev, tag; } T[_ << 2]; IL void Adjust1(RG int x, RG int l, RG int r, RG int v){ T[x].rev = 0, T[x].tag = v--; T[x].sum = v * (r - l + 1
); } IL void Adjust2(RG int x, RG int l, RG int r){ T[x].sum = r - l + 1 - T[x].sum; T[x].rev ^= 1; } IL void Pushdown(RG int x, RG int l, RG int r){ RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1; if(T[x].tag){ Adjust1(ls, l, mid, T[x].tag); Adjust1(rs, mid + 1, r, T[x].tag); T[x].tag = 0; } if(T[x].rev){ Adjust2(ls, l, mid); Adjust2(rs, mid + 1, r); T[x].rev = 0; } } IL void Modify(RG int x, RG int l, RG int r, RG int L, RG int R, RG int v){ if(L <= l && R >= r){ Adjust1(x, l, r, v); return; } Pushdown(x, l, r); RG int mid = (l + r) >> 1; if(L <= mid) Modify(x << 1, l, mid, L, R, v); if(R > mid) Modify(x << 1 | 1, mid + 1, r, L, R, v); T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum; } IL void Reverse(RG int x, RG int l, RG int r, RG int L, RG int R){ if(L <= l && R >= r){ Adjust2(x, l, r); return; } Pushdown(x, l, r); RG int mid = (l + r) >> 1; if(L <= mid) Reverse(x << 1, l, mid, L, R); if(R > mid) Reverse(x << 1 | 1, mid + 1, r, L, R); T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum; } IL int Query(RG int x, RG int l, RG int r){ if(l == r) return l; Pushdown(x, l, r); RG int mid = (l + r) >> 1, ans; if(T[x << 1].sum != mid - l + 1) ans = Query(x << 1, l, mid); else ans = Query(x << 1 | 1, mid + 1, r); T[x].sum = T[x << 1].sum + T[x << 1 | 1].sum; return ans; } int main(RG int argc, RG char *argv[]){ n = Input(), o[++len] = 1; for(RG int i = 1; i <= n; ++i){ opt[i] = Input(), ql[i] = Input(), qr[i] = Input(); o[++len] = ql[i], o[++len] = qr[i]; o[++len] = ql[i] + 1, o[++len] = qr[i] + 1; } sort(o + 1, o + len + 1), len = unique(o + 1, o + len + 1) - o - 1; for(RG int i = 1; i <= n; ++i){ ql[i] = lower_bound(o + 1, o + len + 1, ql[i]) - o; qr[i] = lower_bound(o + 1, o + len + 1, qr[i]) - o; if(opt[i] == 1) Modify(1, 1, len, ql[i], qr[i], 2); else if(opt[i] == 2) Modify(1, 1, len, ql[i], qr[i], 1); else Reverse(1, 1, len, ql[i], qr[i]); printf("%lld\n", o[Query(1, 1, len)]); } return 0; }

CF817F MEX Queries