Statement
下面这个有关区间的游戏,我们称之为“乒乓游戏”。
乒乓游戏可不是乒乓!乒乓好像也和这个游戏没啥关系。这个游戏的主角就
是——区间。对于两个区间,如果(a,b)和(c,d)区间满足 c
某学长讲课时提到可以不打LCT用KDT水过。然后自己too young直接上了KDT,显然没法保证复杂度就T了。然后看了看学长的博客发现要通过合并节点,打标记删除等操作保证复杂度。
代码丑,没写替罪羊重构。
#include
#include
#include
using namespace std;
#define N 100000
#define ts 320
#define inf 1e9
inline char tc(void){
static char fl[10000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,10000,stdin),A==B)?EOF:*A++;
}
inline int read(void){
int a=0,f=1;char c;
while((c=tc())<'0'||c>'9')c=='-'?f=-1:0;
while(c>='0'&&c<='9')a=a*10+c-'0',c=tc();
return a*f;
}
int n,D,f[N+5],root,s,cnt,git,x_1,x_2,y_1,y_2,mx[N+5],mix[N+5],sz,d0[N+5],d1[N+5];
struct tree{
int d[2],L,R,l,r,s;bool exist;
inline bool operator<(const tree&x)const{
return d[D]5],w[N+5];
inline void up(int k,int s){
a[k].L=min(a[k].L,a[s].L),
a[k].R=max(a[k].R,a[s].R);
}
inline void upw(int k,int s){
w[k].L=min(w[k].L,w[s].L),
w[k].R=max(w[k].R,w[s].R);
}
void insert(int k){
int s=root;D=0;
if(!s){root=k;return ;}
while(1){
up(s,k);
if(a[k].d[D]<=a[s].d[D]){if(!a[s].l){a[s].l=k;break;}s=a[s].l;}
else{if(!a[s].r){a[s].r=k;break;}s=a[s].r;}
D^=1;
}
}
void dfs(int k){
if(a[k].exist)w[++sz]=a[k];
if(a[k].l)dfs(a[k].l);
if(a[k].r)dfs(a[k].r);
}
int rebuild(int l,int r,int d){
int mid=l+r>>1;D=d;
nth_element(w+l,w+mid,w+r+1),
w[mid].L=w[mid].d[0],
w[mid].R=w[mid].d[1];
if(l1,d^1);
else w[mid].l=0;
if(r>mid)w[mid].r=rebuild(mid+1,r,d^1);
else w[mid].r=0;
if(w[mid].l)upw(mid,w[mid].l);
if(w[mid].r)upw(mid,w[mid].r);
return mid;
}
void rebuild(){
sz=0,dfs(root),root=rebuild(1,sz,0);
for(int i=1;i<=sz;++i)a[i]=w[i];
}
int gf(int x){
return x==f[x]?x:f[x]=gf(f[x]);
}
bool ok(int s){
return a[s].d[0]>x_1&&a[s].d[0]1]>y_1&&a[s].d[1]bool pd(int s){
int l=a[s].L,r=a[s].R;
if(x_1<=l)return l<=x_2&&r>=y_1;
else return x_1<=r&&y_2>=l;
}
void query(int s){
if(a[s].exist&&ok(s)){
a[s].exist=0;
int x=gf(a[s].s),y=git;
f[x]=y,mx[y]=max(mx[y],mx[x]),mix[y]=min(mix[y],mix[x]);
}
if(a[s].l&&pd(a[s].l))query(a[s].l);
if(a[s].r&&pd(a[s].r))query(a[s].r);
}
int main(void){
register int i,x,y,p,q,l,r;
n=read();
while(n--){
s=read();
switch(s){
case 1:
git=++cnt;
d0[cnt]=x=read(),
d1[cnt]=y=read(),
f[cnt]=cnt,mix[cnt]=x,mx[cnt]=y,
x_1=-inf,x_2=x,y_1=x,y_2=y;
if(root)query(root);
x_1=x,x_2=y,y_1=y,y_2=inf;
if(root)query(root);
x_1=-inf,x_2=x,y_1=y,y_2=inf;
if(root)query(root);
a[cnt].d[0]=a[cnt].L=mix[cnt],
a[cnt].d[1]=a[cnt].R=mx[cnt],
a[cnt].s=cnt,
a[cnt].exist=1,insert(cnt);
if(cnt%ts==0)rebuild();
break;
case 2:
x=read(),y=read();
if(gf(x)==gf(y)){puts("YES");break;}
else{
y=f[y];
if(d1[x]<=mx[y]&&d0[x]>=mix[y]){
puts("YES");break;
}
}
puts("NO");
break;
}
}
return 0;
}