思路:
离线+离散化+线段树
代码:
#includeusing namespace std;#define LL long long #define pb push_back#define ls rt<<1,l,m#define rs rt<<1|1,m+1,rconst int N=1e5+5;int t[N],tree[N*16],lazy[N*16];LL l[N],r[N];vector vc;void push_up(int rt){ tree[rt]=tree[rt<<1]+tree[rt<<1|1];}void push_down(int rt,int l,int r){ int m=(l+r)>>1; if(lazy[rt]==1){ lazy[rt<<1]=lazy[rt<<1|1]=1; tree[rt<<1]=m-l+1; tree[rt<<1|1]=r-m; } else if(lazy[rt]==2){ lazy[rt<<1]=lazy[rt<<1|1]=2; tree[rt<<1]=tree[rt<<1|1]=0; } else if(lazy[rt]==3){ lazy[rt<<1]=3-lazy[rt<<1]; lazy[rt<<1|1]=3-lazy[rt<<1|1]; tree[rt<<1]=m-l+1-tree[rt<<1]; tree[rt<<1|1]=r-m-tree[rt<<1|1]; } lazy[rt]=0;}void build(int rt,int l,int r){ if(l==r){ tree[rt]=0; lazy[rt]=0; return ; } int m=(l+r)>>1; build(ls); build(rs); push_up(rt);}void update(int t,int L,int R,int rt,int l,int r){ if(L<=l&&r<=R){ if(t==1){ tree[rt]=r-l+1; lazy[rt]=1; } else if(t==2){ tree[rt]=0; lazy[rt]=2; } else{ if(lazy[rt]&&l!=r)push_down(rt,l,r);//注意这里,在更新第3种操作时,把之前在这个节点的操作pushdown tree[rt]=r-l+1-tree[rt]; lazy[rt]=3; } return ; } if(lazy[rt])push_down(rt,l,r); int m=(l+r)>>1; if(L<=m)update(t,L,R,ls); if(R>m) update(t,L,R,rs); push_up(rt);}int query(int rt,int l,int r){ if(l==r){ return l; } if(lazy[rt])push_down(rt,l,r); int m=(l+r)>>1; if(tree[rt<<1]!=m-l+1)return query(ls); else return query(rs);}int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin>>n; vc.pb(1LL); for(int i=1;i<=n;i++)cin>>t[i]>>l[i]>>r[i],vc.pb(l[i]),vc.pb(r[i]),vc.pb(r[i]+1),vc.pb(l[i]+1); sort(vc.begin(),vc.end()); vc.erase(unique(vc.begin(),vc.end()),vc.end()); int m=vc.size(); build(1,1,m); for(int i=1;i<=n;i++){ int L=lower_bound(vc.begin(),vc.end(),l[i])-vc.begin()+1; int R=lower_bound(vc.begin(),vc.end(),r[i])-vc.begin()+1; update(t[i],L,R,1,1,m); cout< <