CF319E Ping-Pong 线段树 + vector + 思维
Code:
#include<bits/stdc++.h> #define N 3000009 #define maxn 3000009 #define ll long long #define lson ls[cur] #define inf 1e9 #define rson rs[cur] #define mid ((l+r)>>1) using namespace std; int read() { int x; scanf("%d",&x); return x; } void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); } int rt,m,n,num,cnt,fa[maxn]; int pos[N], ls[N], rs[N]; struct node { int x,y; node(int x=0,int y=0):x(x),y(y){} }p[N]; vector<int>tr[maxn]; int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } void merge(int x,int y) { assert(x!=0); p[y].x=min(p[y].x,p[x].x); p[y].y=max(p[y].y,p[x].y); fa[x]=y; } void add(int cur,int l,int r,int x,int y) { if(!cur) return; for(int i=0;i<tr[cur].size();++i) merge(find(tr[cur][i]), y); tr[cur].clear(); if(l==r) return; if(x<=mid) add(lson,l,mid,x,y); else add(rson,mid+1,r,x,y); } void Add(int &cur,int l,int r,int L,int R,int y) { if(L>R)return; if(!cur)cur=++cnt; if(L<=l&&R>=r) { tr[cur].push_back(y); return; } if(L<=mid) Add(lson,l,mid,L,R,y); if(R>mid) Add(rson,mid+1,r,L,R,y); } int main() { // setIO("input"); m=read(); for(int i=1;i<=m;++i) { int op=read(),x=read(),y=read(); if(op==1) { fa[++num]=num; p[num]=node(x,y); add(rt,-inf,inf,x,num), add(rt,-inf,inf,y,num); if(p[num].x+1<p[num].y) Add(rt,-inf,inf,p[num].x+1,p[num].y-1,num); } else { x=find(x),y=find(y); if (x==y||(p[x].x<p[y].y&&p[x].x>p[y].x)||(p[x].y<p[y].y&&p[x].y>p[y].x)) puts("YES"); else puts("NO"); } } return 0; }