给定一个整数序列为1到n的排列,给出连边的命令,从一个区间选出最大最小值相连,给出询问,问两个点是否连通。
#include<cstdio>
#include<string.h>
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
int n,m,k;
struct node
{
int minn,maxx;
};
#define maxv 101100
node arr[maxv];
int input[maxv];
int c;
int parent[maxv];
void buildtree(int s,int e,int &maximal,int& minimal)
{
if(e-s+1<=0)
{
maximal=minimal=-1;
return;
}
if(e-s+1==0)
{
maximal=minimal=input[e];
return;
}
if(e-s+1==2)
{
maximal=max(input[s],input[e]);
minimal=min(input[s],input[e]);
return;
}
int temp=(s+e)/2;
arr[temp].maxx=input[temp];
arr[temp].minn=input[temp];
int i,j;
buildtree(s,temp-1,i,j);
if(i>=0&&j>=0)
{
if(i>arr[temp].maxx)arr[temp].maxx=i;
if(j<arr[temp].minn)arr[temp].minn=j;
}
buildtree(temp+1,e,i,j);
if(i>=0&&j>=0)
{
if(i>arr[temp].maxx)arr[temp].maxx=i;
if(j<arr[temp].minn)arr[temp].minn=j;
}
maximal=arr[temp].maxx;
minimal=arr[temp].minn;
}
void init()
{
int i,j;
buildtree(0,n-1,i,j);
}
void searchtree(int s,int e,int &maximal,int &minimal,int u,int v)
{
if(e-s+1<=0)
{
maximal=minimal=-1;
return;
}
if(s==u&&v==e)
{
if(e-s+1<=0)
{
maximal=minimal=-1;
return;
}
if(e-s+1==1)
{
maximal=minimal=input[e];
return;
}
if(e-s+1==2)
{
maximal=max(input[s],input[e]);
minimal=min(input[e],input[s]);
return;
}
maximal=arr[(s+e)/2].maxx;
minimal=arr[(s+e)/2].minn;
return;
}
int temp=(s+e)/2;
int i,j;
if(u<=temp&&temp<=v)
{
maximal=input[temp];
minimal=input[temp];
if(u<=temp-1)
{
searchtree(s,temp-1,i,j,u,temp-1);
if(i>maximal)maximal=i;
if(j>=0&&j<minimal)minimal=j;
}
if(v>=temp+1)
{
searchtree(temp+1,e,i,j,temp+1,v);
if(i>maximal)maximal=i;
if(j>=0&&j<minimal)minimal=j;
}
return;
}
if(u>temp)
{
searchtree(temp+1,e,maximal,minimal,u,v);
return;
}
searchtree(s,temp-1,maximal,minimal,u,v);
}
int find(int a)
{
int i=a;
while(parent[a]>=0)
a=parent[a];
while(i!=a)
{
int temp=parent[i];
parent[i]=a;
i=temp;
}
return a;
}
void unionset(int a,int b)
{
int i=find(a),j=find(b);
if(i==j)return;
if(i<j)
{
parent[j]=i;
parent[i]--;
}
else
{
parent[i]=j;
parent[j]--;
}
}
void process()
{
int i;
if(c!=0)
cout<<endl;
c++;
cout<<"CASE "<<c<<endl;
for(i=0;i<n;i++)
{
cin>>input[i];
input[i]--;
parent[i]=-1;
}
init();
cin>>m;
int u,v;
for(i=0;i<m;i++)
{
cin>>u>>v;
u--,v--;
searchtree(0,n-1,u,v,u,v);
unionset(u,v);
}
cin>>k;
for(i=0;i<k;i++)
{
cin>>u>>v;
u--,v--;
if(find(u)==find(v))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
int main()
{
while(cin>>n)
{
process();
}
}