2733: [HNOI2012]永无乡 - BZOJ
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。
Sample Input
5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3
Sample Output
-1
2
5
1
2
平衡树启发式合并
每次合并都把小的拆开,放到大的里面(听说数据很水,随机的,不旋转就可以过,写了一个,然后就pascal的rank1了)
还是正常一点写一个splay吧(不过常数有点大,所以是深度超过32才splay)
const
maxn=;
dep=;
type
node=record
son:array[..]of longint;
size,data,fa:longint;
end;
var
tree:array[..maxn]of node;
f,root:array[..maxn]of longint;
n,m,q:longint; function find(x:longint):longint;
begin
if f[x]=x then exit(x);
f[x]:=find(f[x]);
exit(f[x]);
end; procedure rotate(x,w:longint;var root:longint);
var
y:longint;
begin
y:=tree[x].fa;
tree[y].son[w]:=tree[x].son[w xor ];
if tree[x].son[w xor ]<> then tree[tree[x].son[w xor ]].fa:=y;
tree[x].son[w xor ]:=y;
if y=root then root:=x
else
if tree[tree[y].fa].son[]=y then tree[tree[y].fa].son[]:=x
else tree[tree[y].fa].son[]:=x;
tree[x].fa:=tree[y].fa;
tree[y].fa:=x;
tree[y].size:=tree[tree[y].son[]].size+tree[tree[y].son[]].size+;
end; procedure splay(x:longint;var root:longint);
var
y:longint;
begin
while root<>x do
begin
y:=tree[x].fa;
if y=root then
if tree[y].son[]=x then rotate(x,,root)
else rotate(x,,root)
else
if tree[tree[y].fa].son[]=y then
if tree[y].son[]=x then
begin
rotate(y,,root);
rotate(x,,root);
end
else
begin
rotate(x,,root);
rotate(x,,root);
end
else
if tree[y].son[]=x then
begin
rotate(x,,root);
rotate(x,,root);
end
else
begin
rotate(y,,root);
rotate(x,,root);
end;
end;
tree[x].size:=tree[tree[x].son[]].size+tree[tree[x].son[]].size+;
end; procedure insert(x:longint;var root:longint);
var
now,step:longint;
begin
now:=root;
step:=;
while true do
begin
inc(step);
inc(tree[now].size);
if tree[x].data<tree[now].data then
if tree[now].son[]= then break
else now:=tree[now].son[]
else
if tree[now].son[]= then break
else now:=tree[now].son[];
end;
if tree[x].data<tree[now].data then tree[now].son[]:=x
else tree[now].son[]:=x;
tree[x].size:=;
tree[x].son[]:=;
tree[x].son[]:=;
tree[x].fa:=now;
if step>dep then splay(x,root);
end; procedure dfs(x:longint;var root:longint);
begin
with tree[x] do
begin
if son[]<> then dfs(son[],root);
if son[]<> then dfs(son[],root);
insert(x,root);
end;
end; procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);
v:=find(y);
if u=v then exit;
if tree[root[u]].size<tree[root[v]].size then
begin
dfs(root[u],root[v]);
f[u]:=v;
end
else
begin
dfs(root[v],root[u]);
f[v]:=u;
end;
end; procedure init;
var
i,x,y:longint;
begin
read(n,m);
for i:= to n do
begin
f[i]:=i;
root[i]:=i;
tree[i].size:=;
end;
for i:= to n do
read(tree[i].data);
for i:= to m do
begin
read(x,y);
union(x,y);
end;
end; function ans(k:longint;var root:longint):longint;
var
now,step:longint;
begin
now:=root;
step:=;
if k>tree[now].size then exit(-);
while true do
begin
inc(step);
if k=tree[tree[now].son[]].size+ then
begin
if step>dep then splay(now,root);
exit(now);
end;
if k<=tree[tree[now].son[]].size then now:=tree[now].son[]
else
begin
dec(k,tree[tree[now].son[]].size+);
now:=tree[now].son[];
end;
end;
end; procedure work;
var
i,x,y:longint;
c:char;
begin
readln(q);
for i:= to q do
begin
readln(c,x,y);
if c='Q' then
begin
if (x>n) or (x<) then writeln(-)
else writeln(ans(y,root[find(x)]));
end
else union(x,y);
end;
end; begin
init;
work;
end.
2733: [HNOI2012]永无乡 - BZOJ的更多相关文章
- 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 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
随机推荐
- 踩到两只“bug”
近期在修复ex和头儿的代码时,碰到两个特别点的bug,其实也不能称之为bug,非常简单的用法,稍不严谨点可能就出错了. 第一个是in_array,大家都知道功能是检查一个值是否在数组中,第三个参数传入 ...
- Javascript中的冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序 算法性能分析
阿里面试中有一道题是这样的: 请用JavaScript语言实现 sort 排序函数,要求:sort([5, 100, 6, 3, -12]) // 返回 [-12, 3, 5, 6, 100],如果你 ...
- c++ 11 国标标准方面的异常处理与微软在Visual Studio 2012的异常处理的区别
这段代码: __try { } __except(GetErrorCode()) { } 可以捕获空指针,但是包围在其中的代码不能有自带析构函数的对象.c++ 11 标准里面的auto_ptr关键字, ...
- css3中定义required,focus,valid和invalid样式
css3 提示只适用于高级浏览器: ChromeFirefoxSafariIE9+ valid.invalid.required的定义 代码如下 复制代码 input:required, input ...
- Javascript Error: 11233 Content-Length mismatch
Today I got a error in fiddler: Failed to obtain request body. System.IO.InvalidDataException The re ...
- JavaScript 函数的执行过程
每一个JavaScript函数都是Function对象的一个实例, 它有一个仅供JavaScript引擎存取的内部属性[[Scope]]. 这个[[Scope]]存储着一个作用域的集合, 这个集合就叫 ...
- pgpool常用命令
启动pgpool pgpool -n -d > /tmp/pgpool.log >& & 停止pgpool pgpool stop pgbench的测试命令 pgbench ...
- 【原】从/dev/null重新打开标准输出
今天遇到一个程序,使用了printf输出中间的信息,我也懒得去改.由于此进程被其他进程fork之后,dup2 了标识输入输出到了/dev/null,再通过execvp装载进来.于是,为了看到输出的信息 ...
- open_clientfd(char* hostname,int port)和open_listenfd(int port)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h&g ...
- windows github 搭建与使用
git/github使用以下是全部在命令行使用(windows/github) 注册账户以及创建仓库先在github建立账号和创建仓库,此时为空的仓库 配置git下载并安装 git windows版本 ...