AlenaNuna

导航

线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡

题面:P3224 [HNOI2012]永无乡

题解:

随便写写

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=(1e5)+50,maxm=maxn,maxq=(3e5)+50;
 7 int N,M,W[maxn],fa[maxn],root[maxn],U,V,num_treenode=0,Q,ans,belong[maxn];
 8 char c;
 9 inline int getf(int x){
10     if(fa[x]==x)return fa[x];
11     fa[x]=getf(fa[x]);
12     return fa[x];
13 }
14 struct Tree{int lc,rc,l,r,cnt;}tr[maxn*20];
15 inline void Pushup(int x){
16     int lc=tr[x].lc,rc=tr[x].rc;
17     tr[x].cnt=tr[lc].cnt+tr[rc].cnt;
18     return;
19 }
20 inline void Build(int x,int l,int r,int q){
21     tr[x].l=l;tr[x].r=r;int mid=(l+r)>>1;
22     if(l==r){
23         tr[x].cnt=1;
24         return;
25     }
26     if(q<=mid)Build(tr[x].lc=++num_treenode,l,mid,q);
27     else Build(tr[x].rc=++num_treenode,mid+1,r,q);
28     Pushup(x);
29     return;
30 }
31 inline int Merge(int u,int v){
32     if(!u)return v;
33     if(!v)return u;
34     int l=tr[u].l,r=tr[u].r;
35     if(l==r){
36         tr[u].cnt+=tr[v].cnt;
37         return u;
38     }
39     tr[u].lc=Merge(tr[u].lc,tr[v].lc);
40     tr[u].rc=Merge(tr[u].rc,tr[v].rc);
41     Pushup(u);
42     return u;
43 }
44 inline int Query(int x,int k){
45     int l=tr[x].l,r=tr[x].r,lc=tr[x].lc,rc=tr[x].rc;
46     if(l==r)return l;
47     if(tr[lc].cnt>=k)return Query(lc,k);
48     else return Query(rc,k-tr[lc].cnt);
49 }
50 int main(){
51     scanf("%d%d",&N,&M);
52     for(int i=1;i<=N;i++){
53         scanf("%d",&W[i]);
54         fa[i]=i;
55         belong[W[i]]=i;
56     }
57     for(int i=1;i<=N;i++)
58         Build(root[i]=++num_treenode,1,N,W[i]);
59     for(int i=1;i<=M;i++){
60         scanf("%d%d",&U,&V);
61         int fa1=getf(U),fa2=getf(V);
62         if(fa1!=fa2){
63             Merge(root[fa1],root[fa2]);
64             fa[fa2]=fa1;
65         }
66     }
67     scanf("%d",&Q);
68     while(Q--){
69         c=getchar();
70         while(c!='Q'&&c!='B')c=getchar();
71         scanf("%d%d",&U,&V);
72         if(c=='Q'){
73             int f=getf(U);
74             ans=Query(root[f],V);
75             if(ans==0)ans=-1;else ans=belong[ans];
76             printf("%d\n",ans);
77         }
78         else{
79             int fa1=getf(U),fa2=getf(V);
80             if(fa1!=fa2){
81                 Merge(root[fa1],root[fa2]);
82                 fa[fa2]=fa1;
83             }
84         }
85     }
86     return 0;
87 }

 


By:AlenaNuna

posted on 2019-03-13 21:54  AlenaNuna  阅读(101)  评论(0编辑  收藏  举报