Description
Neverland contains n islands, numbered from 1 to n, each island has its own unique importance, the n islands can be ranked according to the importance, and the ranking is represented by 1 to n
. Some of the islands are connected by huge bridges through which one can go from one island to another.
Island a and island b are said to be connected if they can reach island b through several (including 0) bridges starting from island a . There are now two operations: B xy means to build a new bridge between island x and island y. Q xk means to ask which island is the k-th most important among all the islands currently connected to the island x
, that is, which island is the k-th least important island among all the islands connected to the island x, please output the number of the island .
Input
The first line of the input file is two positive integers n and m separated by spaces, which represent the number of islands and the number of bridges that exist at the beginning, respectively. The next line is n numbers separated by spaces
, describing the importance ranking from island 1 to island n in order. Each of the following m lines is two positive integers ai and bi separated by spaces, indicating that there is a bridge connecting island
ai and island bi at the beginning. The rest of the following section describes the operation. The first line of this section is a positive integer q, indicating a total of q operations. The next q
lines describe each operation in turn. The format of the operation is as described above, starting with the capital letter Q or Start with B, followed by two positive integers up to n, separated by a space between letters and numbers and two numbers.
For 20% of the data n≤1000, q≤1000 For 100% of the data n≤100000, m≤n, q≤300000
Output
A line is output for each Qxk operation in turn, containing an integer representing the number of the island in question. If the island does not exist, output -1.
Sample Input
5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3
Sample Output
-1
2
5
1
2
answer
It was too weak before and thought to write Splay merge. .
Then I took a look today and found that it was just a line segment tree merge,
use a union check to maintain connectivity, and
then heuristically merge it.
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int fa[110000],belong[110000],tot[110000];
int findfa(int x){return fa[x]!=x?fa[x]=findfa(fa[x]):fa[x];}
struct node
{
int lc,rc,c;
}tr[2110000];int trlen;
void add(int &now,int l,int r,int p)
{
if(now==0)now=++trlen;
tr[now].c++;
if(l==r)return ;
int mid=(l+r)/2;
if(p<=mid)add(tr[now].lc,l,mid,p);
else add(tr[now].rc,mid+1,r,p);
}
int rt[110000];
void merge(int &x,int y)
{
if(x==0){x=y;return ;}
if(y==0)return ;
tr[x].c+=tr[y].c;
merge(tr[x].lc,tr[y].lc);
merge(tr[x].rc,tr[y].rc);
}
int Rank[110000];
int findKth(int x,int l,int r,int K)
{
if(tr[x].c<K)return -1;
if(l==r)return Rank[l];
int lc=tr[x].lc,rc=tr[x].rc;
int mid=(l+r)/2;
if(K<=tr[lc].c)return findKth(lc,l,mid,K);
else return findKth(rc,mid+1,r,K-tr[lc].c);
}
int n,m,Q;
char ch[15];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
Rank[x]=i;add(rt[i],1,n,x);
fa[i]=i,tot[i]=1,belong[i]=i;
}
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
int p=findfa(x),q=findfa(y);
if(p!=q)
{
if(tot[p]<tot[q])
{
merge(rt[belong[q]],rt[belong[p]]);
belong[p]=belong[q];
tot[q]+=tot[p];
fa[p]=q;
}
else
{
merge(rt[belong[p]],rt[belong[q]]);
belong[q]=belong[p];
tot[p]+=tot[q];
fa[q]=p;
}
}
}
scanf("%d",&Q);
while(Q--)
{
int x,y;
scanf("%s%d%d",ch+1,&x,&y);
if(ch[1]=='Q')
{
int tmp=findfa(x);
printf("%d\n",findKth(rt[belong[tmp]],1,n,y));
}
else
{
int p=findfa(x),q=findfa(y);
if(p!=q)
{
if(tot[p]<tot[q])
{
merge(rt[belong[q]],rt[belong[p]]);
belong[p]=belong[q];
tot[q]+=tot[p];
fa[p]=q;
}
else
{
merge(rt[belong[p]],rt[belong[q]]);
belong[q]=belong[p];
tot[p]+=tot[q];
fa[q]=p;
}
}
}
}
return 0;
}