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; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11046369.html