[BZOJ2733] Neverland segment tree merge

Description

Neverland contains n Block Island, numbered from 1 to n, each island has its own seat importance of unique importance degree can these n Block Island rankings, ranking scale of 1 to n to represent. Between certain islands connected by the bridge great, you can reach the island from another island by a bridge. If the island from a plurality of through seats (including 0) bridge to reach the island b, a called islands and the island are b communication. There are two modes of operation: B xy represents the construction of a new bridge between the islands and the island x y. Q xk presents to ask all the island currently the island x communication with the first k it is important Which island is that all the islands x communicating the importance of the No. k small island which seat you output number that island . 
 

Input

The first line is input file space-separated two positive integers n and m, respectively represent the number of islands and bridges a number of initially present. N is the number of the next line separated by a space, described importance ranking successively from island to island n is 1. Subsequent lines each m is a space-separated two positive integers ai and bi, represents a bridge is present initially connecting the island ai and bi island. The back rest describing the operation, the portion of the first row is a positive integer q, q represents a total of operations, described in the next line q each operation sequence, the format operation as described above, or with a capital letter Q B starts, followed by between no more than two positive integers n, alphanumeric and two numbers separated by a space. For 20% of the data n≤1000, q≤1000
 
to 100% of the data n≤100000, m≤n, q≤300000 
 

 

answer

Output

For each row to be sequentially output Q xk operation, which contains an integer representing the number of islands interrogated. If the island is not present, then the outputs -1.

 

Segment tree merge template title.

The number for each island to build a tree line weights (logn only one chain length), the tree node maintains the right value of [l, r] island.

For the bridge to the island, but not to be merged Unicom weight segment tree.

Merge operation:

Xy node represents two trees to merge, if x * y == 0, then x or y or x & y not present, i.e. sub-tree does not need to merge weights, without changes, pointing directly to the parent node;

Otherwise, the weight value is added to y x, the tree is also possible to reduce the space complexity with root [x], and then recursively merge (). siz [x] + = siz [y]; equivalent siz [x] = siz [lc [x]] + siz [rc [x]]; were combined directly, updating (subtrees of subtrees may only be changed to point )

Find kth:

With balanced tree, the binary tree, the line weights can, if K <= SIZ [ LC [RT] ], described in the kth left subtree, and vice versa in the kth position in the right subtree and right subtree of k-siz [lc [rt]] (balanced tree because it is different from the segment tree node different meaning)

With disjoint-set maintenance Unicom relationship that is whether the merger weights tree line.

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define reg register
#define F(i,a,b) for(i=a;i<=b;++i)
using namespace std;
int lc[2000005],rc[2000005],rk[100005],fa[100005],siz[2000005],rt[100005],o;
int find(int x)
{
    if(fa[x]==x) return x;
    return fa[x]=find(fa[x]);
}
void insert(int &root,int l,int r,int w)
{
    root=++o;
    siz[root]=1;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(w<=mid) insert(lc[root],l,mid,w);
    else insert(rc[root],mid+1,r,w);
    siz[root]=siz[lc[root]]+siz[rc[root]];
}
int merge(int x,int y)
{
    if(x*y==0) returnY + X;                 // the xy subtrees do not overlap, do not change, only the change point 
    SIZ [X] + = SIZ [Y];                         // weight incorporated into the X 
    LC [X] = Merge (LC [X], LC [Y]); 
    RC [X] = Merge (RC [X], RC [Y]); 
    SIZ [X] = SIZ [LC [X]] + SIZ [RC [X]];
     return X; 
} 
int ASK ( int RT, int L, int R & lt, int K) 
{ 
    IF (R & lt == L) return RK [L];
     int MID = (L + R & lt) >> . 1 ;
     IF (K <= SIZ [LC [RT] ]) return ASK (LC [RT], L, MID, K);
    else return ask(rc[rt],mid+1,r,k-siz[lc[rt]]);
}
void merge2(int x,int y)
{
    int a,b;
    a=find(x); b=find(y);
    if(a!=b) fa[b]=a,rt[a]=merge(rt[a],rt[b]);            //不能换,x为合并后根 
}
int main()
{
    int n,m,q;
    scanf("%d%d",&n,&m);
    reg int i,t,a,b;
    F(i,1,n)
        scanf("%d",&t),rk[t]=i,fa[i]=i,insert(rt[i],1,n,t);
    F(i,1,m)
        scanf("%d%d",&a,&b),merge2(a,b);
    scanf("%d",&q);
    reg char s[5];
    while(q--)
    {
        scanf("%s",s);
        scanf("%d %d",&a,&b);
        if(s[0]=='B') merge2(a,b);
        else printf("%d\n",siz[rt[find(a)]]<b?-1:ask(rt[find(a)],1,n,b));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/hzoi-yzh/p/11008122.html