题意
题面:www.lydsy.com/JudgeOnline/upload/task.pdf
题解
感觉不是特别难的一个题
思路想出来了,但是没有用到区间长度是递增的
所以时间复杂度不对啊。。
考虑到区间长度是递增的,所以其实我们对于之前的点
如果他有一个端点在某一个区间里面,那么他们就是可以互相到达的
这个的话用并查集缩点就可以了
然后线段树优化一下
不想多说了。。具体代码
CODE:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int MAX=(1<<30);
const int N=100005*2;
int n;
int A[N];//所有存在的数
struct qq { int l,r,op; }s[N];
struct qr { int l,r; int s1,s2; vector<int> c; }tr[N*2];int num=0;
void LSH ()
{
sort(A+1,A+1+A[0]);
int ooo=1;
for (int u=2;u<=A[0];u++)
if (A[u]!=A[ooo])
A[++ooo]=A[u];
for (int u=1;u<=n;u++)
{
if (s[u].op==2) continue;
int l=1,r=ooo;
while (l<=r)
{
int mid=(l+r)>>1;
if (s[u].l==A[mid]) {s[u].l=mid;break;}
else if (s[u].l>A[mid]) l=mid+1;
else r=mid-1;
}
l=1,r=ooo;
while (l<=r)
{
int mid=(l+r)>>1;
if (s[u].r==A[mid]) {s[u].r=mid;break;}
else if (s[u].r>A[mid]) l=mid+1;
else r=mid-1;
}
}
}
void bt (int l,int r)
{
int a=++num;
tr[a].l=l;tr[a].r=r;
if (l==r) return ;
int mid=(l+r)>>1;
tr[a].s1=num+1;bt(l,mid);
tr[a].s2=num+1;bt(mid+1,r);
}
int tot,belong[N];
int L[N],R[N];
int f[N];
int find (int x){return f[x]==x?f[x]:f[x]=find(f[x]);}
void Del (int now,int x)
{
if (tr[now].c.size())
{
for (int u=0;u<tr[now].c.size();u++)
{
int id=tr[now].c[u];
f[find(id)]=tot;
L[tot]=min(L[tot],L[id]);
R[tot]=max(R[tot],R[id]);
}
tr[now].c.clear();
}
if (tr[now].l==tr[now].r) return ;
int mid=(tr[now].l+tr[now].r)>>1;
int s1=tr[now].s1,s2=tr[now].s2;
if (x<=mid) Del(s1,x);
else Del(s2,x);
}
void update (int now,int l,int r)
{
if (l>r) return ;
if (tr[now].l==l&&tr[now].r==r)
{
tr[now].c.push_back(tot);
return ;
}
int mid=(tr[now].l+tr[now].r)>>1;
int s1=tr[now].s1,s2=tr[now].s2;
if (r<=mid) update(s1,l,r);
else if (l>mid) update(s2,l,r);
else update(s1,l,mid),update(s2,mid+1,r);
}
int main()
{
scanf("%d",&n);
for (int u=1;u<=n;u++)
{
scanf("%d%d%d",&s[u].op,&s[u].l,&s[u].r);
if (s[u].op==1)
{
A[++A[0]]=s[u].l;A[++A[0]]=s[u].r;
}
}
LSH();
bt(1,A[0]);
for (int u=1;u<=n;u++)
{
if (s[u].op==1)
{
tot++;
L[tot]=s[u].l;
R[tot]=s[u].r;
f[tot]=tot;
Del(1,s[u].l);
Del(1,s[u].r);
update(1,L[tot]+1,R[tot]-1);
}
else
{
int y=find(s[u].l),x=find(s[u].r);
if (x==y||(L[x]<L[y]&&L[y]<R[x])||(L[x]<R[y]&&R[y]<R[x]))
printf("YES\n");
else printf("NO\n");
}
}
return 0;
}