zoukankan      html  css  js  c++  java
  • [BZOJ2733][HNOI2012]永无乡 线段树合并

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733

    我们对每一个连通块建一棵以排名为键值的权值线段树,询问就可以用二分的方法。

    然后对于块与块间加边,我们用并查集维护连通性,每次合并两个块的时候,因为线段树结构相同,可以直接合并就行了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 int inline readint(){
     6     int Num;char ch;
     7     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
     8     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
     9     return Num;
    10 }
    11 void outint(int x){
    12     if(x>=10) outint(x/10);
    13     putchar(x%10+'0');
    14 }
    15 int N,M,Q;
    16 int a[100010],re[100010];
    17 int Rt[100010],lc[2000010],rc[2000010],cnt=0;
    18 int sum[2000010];
    19 int fa[100010];
    20 int inline Getfa(int x){
    21     return fa[x]==x?x:fa[x]=Getfa(fa[x]);
    22 }
    23 void Pushup(int &rt){
    24     sum[rt]=sum[lc[rt]]+sum[rc[rt]];
    25 }
    26 void Insert(int &rt,int l,int r,int x){
    27     if(!rt) rt=++cnt;
    28     if(l==r){
    29         sum[rt]=1;
    30         return;
    31     }
    32     int mid=l+r>>1;
    33     if(x<=mid) Insert(lc[rt],l,mid,x);
    34     else Insert(rc[rt],mid+1,r,x);
    35     Pushup(rt);
    36 }
    37 int Merge(int x,int y){
    38     if(!x||!y) return x+y;
    39     lc[x]=Merge(lc[x],lc[y]);
    40     rc[x]=Merge(rc[x],rc[y]);
    41     Pushup(x);
    42     return x;
    43 }
    44 int Qry(int rt,int l,int r,int x){
    45     if(l==r) return l;
    46     int mid=l+r>>1;
    47     if(sum[lc[rt]]>=x) return Qry(lc[rt],l,mid,x);
    48     else return Qry(rc[rt],mid+1,r,x-sum[lc[rt]]);
    49 }
    50 int main(){
    51     N=readint();
    52     M=readint();
    53     for(int i=1;i<=N;i++){
    54         a[i]=readint();
    55         Insert(Rt[i],1,N,a[i]);
    56         re[a[i]]=i;
    57     }
    58     for(int i=1;i<=N;i++) fa[i]=i;
    59     for(int i=1;i<=M;i++){
    60         int A=readint(),
    61             B=readint(),
    62             fA=Getfa(A),
    63             fB=Getfa(B);
    64         fa[fB]=fA;
    65         Rt[fA]=Merge(Rt[fA],Rt[fB]);
    66     }
    67     Q=readint();
    68     for(int i=1;i<=Q;i++){
    69         char opt[5];
    70         scanf("%s",opt);
    71         int x=readint(),
    72             y=readint();
    73         switch(opt[0]){
    74             case 'Q':
    75                 x=Getfa(x);
    76                 if(sum[Rt[x]]<y){
    77                     puts("-1");
    78                     break;
    79                 }
    80                 outint(re[Qry(Rt[x],1,N,y)]);
    81                 putchar('
    ');
    82                 break;
    83             case 'B':
    84                 x=Getfa(x);
    85                 y=Getfa(y);
    86                 if(x==y) break;
    87                 fa[y]=x;
    88                 Rt[x]=Merge(Rt[x],Rt[y]);
    89                 break;
    90         }
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    编程用外星人宏建设置教程(在网上找了好久没几个相关帖子,自己研究写下来留个备忘吧)
    通过selenium+pyautogui模拟登陆淘宝(完美实现)
    python之字符串的五种拼接方式
    python之批量文件重命名
    爬虫系列之链家的信息爬取及数据分析
    跟潭州学院的强子老师学习网络爬虫---爬取全书网
    Python之编写测试用例,unittest模块中的TestCase类中的六种断言方法,以及setUp()函数。
    Python学习之路
    GridBagLayout的帮助类
    eclipse和cygwin搭建C++环境的修正版本
  • 原文地址:https://www.cnblogs.com/halfrot/p/7630048.html
Copyright © 2011-2022 走看看