Codeforces 817F MEX Queries
题意:对一个维护三种操作:1.将[l..r]中的数全部加入集合中。2.将集合中[l..r]范围内的数删去。3.将集合中在[l..r]中的数删去,并将之前不在集合中的数加入集合
考虑到最近线段树总是写爆,我决定在CF上切几道水题练练手,于是找到了这题。。。一开始想了想感觉不太会做,后来发现好像可以离散化后用线段树维护区间1的个数来解决。1就是将[l..r]中的所有数赋值为1,2反之,3就是区间长度-当前1的个数。然后敲了很久,最后惊喜地发现我又特么敲爆了。。。调了好久发现是离散化出了问题。。。
#include<bits/stdc++.h> using namespace std; #define MAXN 300000+10 typedef long long LL; struct tree{int sum,tag,flag;}tr[10*MAXN]; int n,pre=1,tot=0,pos[MAXN],opt[MAXN]; LL lp[MAXN],rp[MAXN],num[MAXN],b[MAXN*2]; void pushup(int k){tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;} void pushdown(int k,int l,int r){ int mid=(l+r)>>1; if(tr[k].tag!=-1){ tr[k<<1].sum=(mid-l+1)*tr[k].tag; tr[k<<1|1].sum=(r-mid)*tr[k].tag; tr[k<<1].tag=tr[k<<1|1].tag=tr[k].tag; tr[k<<1].flag=tr[k<<1|1].flag=0; tr[k].tag=-1; } if(tr[k].flag){ tr[k<<1].sum=(mid-l+1)-tr[k<<1].sum; tr[k<<1|1].sum=(r-mid)-tr[k<<1|1].sum; tr[k<<1].flag^=1; tr[k<<1|1].flag^=1; tr[k].flag=0; } } void build(int k,int l,int r){ tr[k].flag=0;tr[k].tag=-1; if(l==r){ tr[k].sum=0; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } void cover(int k,int l,int r,int L,int R,int t){ // printf("%d %d %d\n",k,l,r); if(l>=L&&r<=R){ tr[k].sum=(r-l+1)*t; tr[k].tag=t; tr[k].flag=0; return; } pushdown(k,l,r); int mid=(l+r)>>1; if(R<=mid)cover(k<<1,l,mid,L,R,t); else if(L>mid)cover(k<<1|1,mid+1,r,L,R,t); else cover(k<<1,l,mid,L,R,t),cover(k<<1|1,mid+1,r,L,R,t); pushup(k); } void roate(int k,int l,int r,int L,int R){ // printf("%d %d %d\n",k,l,r); if(l>=L&&r<=R){ tr[k].sum=(r-l+1)-tr[k].sum; tr[k].flag^=1; return; } pushdown(k,l,r); int mid=(l+r)>>1; if(R<=mid)roate(k<<1,l,mid,L,R); else if(L>mid)roate(k<<1|1,mid+1,r,L,R); else roate(k<<1,l,mid,L,R),roate(k<<1|1,mid+1,r,L,R); pushup(k); } int query(int k,int l,int r){ // printf("%d %d %d\n",k,l,r); if(l==r)return l; pushdown(k,l,r); int mid=(l+r)>>1; if(tr[k<<1].sum<mid-l+1)return query(k<<1,l,mid); else return query(k<<1|1,mid+1,r); pushup(k); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%I64d%I64d",&opt[i],&lp[i],&rp[i]); rp[i]++; b[++tot]=num[tot]=lp[i]; b[++tot]=num[tot]=rp[i]; } num[++tot]=b[tot]=pos[tot]=1; sort(b+1,b+tot+1); int d=unique(b+1,b+tot+1)-b-1; for(int i=1;i<=tot;i++)pos[i]=lower_bound(b+1,b+d+1,num[i])-b; build(1,1,d); for(int i=1;i<=n;i++){ int l=pos[i*2-1],r=pos[i*2]-1; if(opt[i]==1)cover(1,1,d,l,r,1); else if(opt[i]==2)cover(1,1,d,l,r,0); else roate(1,1,d,l,r); printf("%I64d\n",b[query(1,1,d)]); } return 0; }
Hello World