CF817F MEX Queries
阿新 • • 發佈:2020-07-28
https://www.luogu.com.cn/problem/CF817F
線段樹
資料範圍極大,需要離散化
可以轉換一下操作:
\(1.\)將\([l,r]\)區間賦值為\(1\)
\(2.\)將\([l,r]\)區間賦值為\(0\)
\(3.\)將\([l,r]\)區間\(0\)變成\(1\),\(1\)變成\(0\)
用\(lazy\)記錄當前位置的狀態
\(0:\)該區間沒有操作
\(1:\)該區間被全部覆蓋
\(2:\)該區間被全部刪除
\(3:\)該區間被全部反轉
注意,\(lazy_1,lazy_2\)可以直接覆蓋以前的\(lazy\),但操作\(lazy_3\)需要判斷一下
\(lazy_0+lazy_3=lazy_3\)
\(lazy_1+lazy_3=lazy_2\)
\(lazy_2+lazy_3=lazy_1\)
\(lazy_3+lazy_3=lazy_0\)
\(OK!\)
\(C++ Code:\)
#include<cstdio> #include<iostream> #include<algorithm> #define ll long long #define N 200005 using namespace std; int n,m,cnt,cc; struct Ques { int opt; ll l,r; }q[N]; ll g[N*3]; struct node { int s,lazy; }t[N << 5]; void down_tag(int p,int l,int r,int z) { switch (z) { case 1: t[p].s=r-l+1; t[p].lazy=1; break; case 2: t[p].s=0; t[p].lazy=2; break; case 3: t[p].s=r-l+1-t[p].s; switch (t[p].lazy)//lazy3的特判 { case 0: t[p].lazy=3; break; case 1: t[p].lazy=2; break; case 2: t[p].lazy=1; break; case 3: t[p].lazy=0; break; } break; } } void down(int p,int l,int r) { if (!t[p].lazy) return; int mid=(l+r) >> 1; down_tag(p+p,l,mid,t[p].lazy); down_tag(p+p+1,mid+1,r,t[p].lazy); t[p].lazy=0; } void change(int p,int l,int r,int x,int y,int z) { if (l>y||r<x) return; if (x<=l&&r<=y) { down_tag(p,l,r,z); return; } down(p,l,r); int mid=(l+r) >> 1; change(p+p,l,mid,x,y,z); change(p+p+1,mid+1,r,x,y,z); t[p].s=t[p+p].s+t[p+p+1].s; } #define dis(x,y) (y-x+1) int query(int p,int l,int r) { if (l==r) return l; down(p,l,r); int mid=(l+r) >> 1; if (t[p+p].s<dis(l,mid)) return query(p+p,l,mid); else return query(p+p+1,mid+1,r); } int main() { scanf("%d",&m); g[++cnt]=1; for (int i=1;i<=m;i++) { scanf("%d%lld%lld",&q[i].opt,&q[i].l,&q[i].r); g[++cnt]=q[i].l; g[++cnt]=q[i].r; g[++cnt]=q[i].r+1; } sort(g+1,g+cnt+1);//離散化 cc=unique(g+1,g+cnt+1)-g-1; for (int i=1;i<=m;i++) { q[i].l=lower_bound(g+1,g+cc+1,q[i].l)-g; q[i].r=lower_bound(g+1,g+cc+1,q[i].r)-g; change(1,1,cc,q[i].l,q[i].r,q[i].opt); printf("%lld\n",g[query(1,1,cc)]); } return 0; }