BZOJ 2733 【HNOI2012】 永无乡
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】 永无乡的更多相关文章
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
2733: [HNOI2012]永无乡 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1167 Solved: 607[Submit][Status ...
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
不难...treap + 启发式合并 + 并查集 搞搞就行了 --------------------------------------------------------------------- ...
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
2733: [HNOI2012]永无乡 题意:加边,询问一个连通块中k小值 终于写了一下splay启发式合并 本题直接splay上一个节点对应图上一个点就可以了 并查集维护连通性 合并的时候,把siz ...
- bzoj 2733: [HNOI2012]永无乡 -- 线段树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...
- Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3955 Solved: 2112[Submit][Statu ...
- Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...
- 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡
题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...
- bzoj 2733: [HNOI2012]永无乡
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
随机推荐
- 全面理解JavaScript中的闭包的含义及用法
1.什么是闭包 闭包:闭包就是能够读取其他函数内部变量的函数;闭包简单理解成“定义在一个函数内部的函数”. 闭包的形式:即内部函数能够使用它所在级别的外部函数的参数,属性或者内部函数等,并且能在包含它 ...
- laravel excel迁移到lumen
1.简介 Laravel Excel 在 Laravel 5 中集成 PHPOffice 套件中的 PHPExcel ,从而方便我们以优雅的.富有表现力的代码实现Excel/CSV文件的导入和 导出 ...
- TechEd2013 Shanghai Hol Session PPT Share
上个月去上海参加了TechEd 2013,并且参与了Hands-on-Lab环节,作为讲师引导大家完成<Local DB in WP8>实验的内容.由于实验的内容采用MVVM架构完成,因此 ...
- JSON格式互转集合
在工作中我们经常会遇到格式转换的问题,有的时候是将JSON转换成DataTable.DataSet或是List等,也有可能将DataTable.DataSet或是List转换成JSON的,抽了点时间把 ...
- Web环境使用相对路径发布Webservice
常我们的Webservice服务的发布地址都将是一个相对路径,在与Spring一起使用时我们需要引入Cxf配置Webservice的schema,如jaxws,用以定义对应的Webservice. & ...
- c#操作IIS站点
/// <summary> /// 获取本地IIS版本 /// </summary> /// <returns></returns> public st ...
- 烂泥:【转】rsync命令参数详解
本文由秀依林枫提供友情赞助,首发于烂泥行天下. rsync安装完毕后,我们可以通过rsync –help查看rysnc命令的使用.如下: 有关rsync的命令格式,在此我们就不多介绍了.如果有想了解的 ...
- x01.FileProcessor: 文件处理
姚贝娜落选,意味着好声音失败.“我们在一起”的精彩亮相,正如同她的歌声,愈唱愈高,直入云霄. 文件处理,无外乎加解密,加解压,分割合并.本着“快舟"精神,花了两天时间,写了个小程序,基本能满 ...
- 用php生成静态html页面(通用2种方法)
因为每次用户点击动态链接的时候都会对服务器发送数据查询的要求 对于一个访问量可能达百万千万级别的网站来说 这无疑是服务器一个大大的负担 所以把动态数据转换成静态html页面就成了节省人力物力的首选 因 ...
- ASP.NET Core 1.0 安装并发布到Centos 7.2 使用jexus 5.8.2
安装运行环境 sudoyuminstall libunwind libicu 下载.net core https://www.microsoft.com/net/download 下载完后上传文件 安 ...