[bzoj2733][Line segment tree merge][Union search]Never Township

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324605844&siteId=291194637