• 线段树合并+并查集 || 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
    ",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

  • 相关阅读:
    ID3决策树---Java
    Static、final、abstract、接口、构造方法及java语法总结
    集合类 Collection
    String、StringBuilder
    java基础类:Object类和Math类
    如何快速定位TempDB产生问题
    教你实现图片的惰性加载
    如何在 apache 中开启 gzip 压缩服务
    Data URI 应用场景小结
    获取图片base64编码的几种方法
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10526885.html
Copyright © 2020-2023  润新知