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 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
随机推荐
- sqlsever 关于索引
索引: 在sqlserver中,存储的单位最小是页,页是不可再分的B树:初衷是减少对磁盘的扫描次数,如果一个表或者索引没有使用B树(对于没有聚集索引的表是使用 Heap 堆进行存储的),那么查找一个数 ...
- 制作BibTex文件
上一篇日志中讲到了在LaTeX中使用BibTex管理参考文献,这篇日志具体总结下如何制作BibTex文件. 制作BibTex文件,主要有以下几种方法: 手工制作: 直接从期刊数据库中下载: 借助Goo ...
- 第三十九篇、NavBar动态隐藏、设置透明、毛玻璃效果
1.动态隐藏 - (void)viewDidLoad { [super viewDidLoad]; if ([self respondsToSelector:@selector(automatical ...
- SQL通过日期计算年龄
首先建立一个表如下: ======================= BirthDay datetime not null Age 通过公式计算得出 ======================= 以 ...
- NodeJS V8 GC概览
[A tour of V8: Garbage Collection] http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection 基本是 ...
- js笔记——浏览器及版本判断
判断IE浏览器的时候注意需要做两个判断 一个是msie 一个是Edge function myBrowser(){ var userAgent = navigator.userAgent; //取得浏 ...
- [GeekBand] 面向对象的设计模式(C++)(1)
一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心. 这样,你就能一次又一次 地使用该方案而不必做重复劳动. 0. 从面向对象谈起 底层思维与抽象思维: 底层思维要求程序员&q ...
- HP平台由于变量声明冲突导致程序退出时的core
最近遇到一个莫名的问题,在HP-UX B.11.31 U ia64平台下,程序PetriService在接收到产品化退出或Ctrl-C时,程序在main函数返回后析构全局的CTQueue<SMs ...
- Nginx日志按天分割
核心思想:使用crontab在每日23:59执行日志分割. 1.配置nginx日志信息,vim /etc/logrotate.d/nginx /var/log/nginx/*.log { nocomp ...
- TCP/IP:链路层
链路层主要目的: 1. 为IP模块发送和接收IP数据报. 2. 为ARP模块发送ARP请求和接收ARP应答. 3. 为RARP发送RARP请求和接收RARP应 ...