Description

永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛。如果从岛 a 出发经过若干座(含 0 座)桥可以到达岛 b,则称岛 a 和岛 b 是连 通的。现在有两种操作:B x y 表示在岛 x 与岛 y 之间修建一座新桥。Q x k 表示询问当前与岛 x连通的所有岛中第 k 重要的是哪座岛,即所有与岛 x 连通的岛中重要度排名第 k 小的岛是哪 座,请你输出那个岛的编号。

Input

输入文件第一行是用空格隔开的两个正整数 n 和 m,分别 表示岛的个数以及一开始存在的桥数。接下来的一行是用空格隔开的 n 个数,依次描述从岛 1 到岛 n 的重要度排名。随后的 m 行每行是用空格隔开的两个正整数 ai 和 bi,表示一开始就存 在一座连接岛 ai 和岛 bi 的桥。后面剩下的部分描述操作,该部分的第一行是一个正整数 q, 表示一共有 q 个操作,接下来的 q 行依次描述每个操作,操作的格式如上所述,以大写字母 Q 或B 开始,后面跟两个不超过 n 的正整数,字母与数字以及两个数字之间用空格隔开。

对于 20%的数据 n≤1000,q≤1000
对于 100%的数据 n≤100000,m≤n,q≤300000

Output

对于每个 Q x k 操作都要依次输出一行,其中包含一个整数,表示所询问岛屿的编号。如果该岛屿不存在,则输出-1。

  原来HN省选也有这么水的题233~

  这道题这么显然,区间k小数,那么要么就是平衡树,要么就是权值线段树,而这两个东西在合并时都可以启发式合并。所谓的启发式就是每次把两棵树合并的时候,把节点数较少的那一颗给拆了,每个节点依次插入到另一颗树中去。这样由于每次一个节点重新插入时它所在的树大小都会翻倍,这样也就保证了每个节点最多被插入$\log n$次。于是就可以愉快的解决了。时间复杂度$O(n\log ^2 n)$。

  UPD:听说这样子的线段树合并是$O(n\log n)$的,因为每个节点只会被访问到子树大小那么多次,因此复杂度为$O(n\log n)$。

  我写的权值线段树,有点丑,凑合着看吧。 下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 100010
#define MAXN maxn*20 using namespace std;
typedef long long llg; int n,m,q,a[maxn],fa[maxn],siz[maxn],fr[maxn];
int rt[maxn],le[MAXN],ri[MAXN],sumv[MAXN],tt; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} int find(int x){return fa[fa[x]]==fa[x]?fa[x]:fa[x]=find(fa[x]);}
void insert(int u,int x){
int l=1,r=n,mid; fr[x]=u;
while(l!=r){
mid=(l+r)>>1; sumv[u]++;
if(x<=mid){
if(!le[u]) le[u]=++tt;
r=mid,u=le[u];
}
else{
if(!ri[u]) ri[u]=++tt;
l=mid+1,u=ri[u];
}
}
sumv[u]++;
} int merge(int u1,int u2){
if(!u1 || !u2) return u1+u2;
le[u1]=merge(le[u1],le[u2]);
ri[u1]=merge(ri[u1],ri[u2]);
sumv[u1]+=sumv[u2];
return u1;
} int work(int u,int k){
if(k>sumv[u]) return -1;
int l=1,r=n,mid;
while(l!=r){
mid=(l+r)>>1;
if(sumv[le[u]]>=k) u=le[u],r=mid;
else k-=sumv[le[u]],l=mid+1,u=ri[u];
}
return fr[l];
} int main(){
File("a");
n=getint(); m=getint(); tt=n;
for(int i=1;i<=n;i++) siz[i]=1,fa[i]=i,rt[i]=i,insert(rt[i],getint());
while(m--){
int x=getint(),y=getint();
x=find(x); y=find(y);
if(siz[x]>siz[y]) swap(x,y);
fa[x]=y; siz[y]+=siz[x];
rt[y]=merge(rt[y],rt[x]);
}
q=getint();
while(q--){
char c=getchar();
while(c!='Q' && c!='B') c=getchar();
int x=getint(),y=getint();
if(!x && !y) continue;
if(c=='B'){
x=find(x); y=find(y);
if(siz[x]>siz[y]) swap(x,y);
fa[x]=y; siz[y]+=siz[x];
rt[y]=merge(rt[y],rt[x]);
}
else printf("%d\n",work(rt[find(x)],y));
}
return 0;
}

BZOJ 2733 【HNOI2012】 永无乡的更多相关文章

  1. BZOJ 2733: [HNOI2012]永无乡 启发式合并treap

    2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. bzoj 2733: [HNOI2012]永无乡 离线+主席树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1167  Solved: 607[Submit][Status ...

  3. BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)

    不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...

  4. BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]

    2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...

  5. bzoj 2733: [HNOI2012]永无乡 -- 线段树

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...

  6. Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3955  Solved: 2112[Submit][Statu ...

  7. Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...

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

    题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...

  9. bzoj 2733: [HNOI2012]永无乡

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  10. bzoj 2733 : [HNOI2012]永无乡 (线段树合并)

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

随机推荐

  1. 省市县三级联动 sql语句

    发现在网上的省市县三级联动大部分是mysql的.就算是sqlserver的,也不准确.于是就把mysql的给改了下,适用sqlserver.sql语句如下: CREATE TABLE Dic_Area ...

  2. 学习 java命令

    依稀记得自己第一次编译*.java文件,第一次运行*.class文件.但是六七年过去了,现在运行java写的程序更多的是用tomcat这种web容器.最近有个小需求,写一个监控zookeeper集群的 ...

  3. 解决Windows 8系统假死的方法

    大部分半卡死的现象是因为Dynamic Tick的一个Bug.Dynamic Tick是NT 6.2内核的一个新功能(其实Linux早就有了),原理的话大概是在空闲的时候把CPU完全暂停,来节省电量. ...

  4. equals()和hashCode()之间的关系

    在Java的基类java.lang.Object中有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() 对这两个方法的 ...

  5. 按要求编写Java应用程序: (1)编写西游记人物类(XiYouJiRenWu) 其中属性有:身高(height),名字(name),武器(weapon) 方法有:显示名字(printName),显示武器(printWeapon) (2)在主类的main方法中创建二个对象:zhuBaJie,sunWuKong。并分别为他 们的两个属性(name,weapon)赋值,最后分别调用printName,

    package com.hanqi.test; public class xiyoujirenwu { private double height;// 身高 private String name; ...

  6. solrconfig.xml介绍

    说明:请务必先了解如下知识,否则阅读本文会晕. Solr术语介绍:SolrCloud,单机Solr,Collection,Shard,Replica,Core之间的关系 Solr通过三个主要文件来作配 ...

  7. pt-diskstats 报错 Can't locate Time/HiRes.pm in @INC

    调用 pt-diskstats 时报错如下Can't locate Time/HiRes.pm in @INC [root@localhost ~]# pt-diskstats Can't locat ...

  8. Linux基本操作命令之文件查看cat more less tail head

    cat 参考之前博客:Linux基础命令之cat使用方法大全 more 命令 命令:more使用权限:所有使用者使用方式:more [选项] filename说明:类似于cat,不过会一页一页的显示内 ...

  9. android 新建项目中去掉标题栏

    1.新建new android application project theme选none 并打钩创建一个Blank Activity 运行如下图所示: 2.若想把标题栏去掉,更改Manifestr ...

  10. 双核CPU,跑程序会报rcu_sched_state detected stalls on CPUs/tasks 错误

    有一份SDK,之前跑在PPC405EX上没问题。最近换平台,CPU使用了PowerPC的P1020,双核。linux版本也升级到了3.0.48版本。升级之后出现了一个问题:SDK里面的程序跑一段时间之 ...