原题传送门

题意:给你N个带权点,一开始相互独立(每个点视为单独一个集合),有2种操作:1)合并2个集合;2)查询包含某元素集合内的权值第k小点编号。

解题思路:显然合并就是并查集,而查询则是平衡树实现。

考虑对每个集合开一棵平衡树,这样的话直接合并2棵平衡树的效率最坏是\( n \log n \)的,显然会TLE。

考虑使用启发式合并,这样就可以将合并的集合树的深度严格限制在\( \log n \)内,于是每次合并的效率就约为 \( \log^{2} n \)的。这样就不会TLE了。

时间效率:操作1:\( \log^{2} n \) ; 操作2: \( \log n \).

注意一下如果已经在一个集合内就不要合并了。

总复杂度:\( O( (m+q) \log^{2} n) \) / \( O(n) \).

AC代码:(1312ms/4688KB on BZOJ)

#include <stdio.h>
#define r register
#define MN 100005
#define getchar() (S==TT&&(TT=(S=BB)+fread(BB,1,1<<15,stdin),S==TT)?EOF:*S++)
char BB[<<],*S=BB,*TT=BB;
inline int read(){
r int x=,f=; r char ch=getchar();
while (ch<''||ch>'') f=ch=='-'?-:,ch=getchar();
while (ch>=''&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x*f;
}inline int rad(){
static int x=;
return x^=x<<,x^=x>>,x^=x<<;
}
struct treap{
treap *ls,*rs;
int sz,val,ord,pri;
void combine(){
sz=;
if (ls!=NULL) sz+=ls->sz;
if (rs!=NULL) sz+=rs->sz;
}treap(int val,int ord):ord(ord),val(val){ls=rs=NULL,sz=,pri=rad();}
}*root[MN];
inline void lturn(treap* &x){r treap *y=x->rs; x->rs=y->ls; y->ls=x; y->sz=x->sz; x->combine(); x=y;}
inline void rturn(treap* &x){r treap *y=x->ls; x->ls=y->rs; y->rs=x; y->sz=x->sz; x->combine(); x=y;}
inline void Insert(treap* &x,int val,int ord){
if (x==NULL) {x=new treap(val,ord);return;}x->sz++;
if (val<x->val){Insert(x->ls,val,ord);if (x->ls->pri<x->pri) rturn(x);}
else{Insert(x->rs,val,ord);if (x->rs->pri<x->pri) lturn(x);}
}
inline void merge(treap* &o,treap* &x){
if (o==NULL) return;
merge(o->ls,x);merge(o->rs,x);
Insert(x,o->val,o->ord);
delete o;o=NULL;return;
}
inline int query(treap *x,int k){
if (x==NULL||k<||k>x->sz) return -;
if (x->ls==NULL){
if (k==) return x->ord;
return query(x->rs,k-);
}
if (k<=x->ls->sz) return query(x->ls,k);
if (k==x->ls->sz+) return x->ord;
return query(x->rs,k-x->ls->sz-);
}
int fa[MN],n,q;
inline int getfa(int x){return fa[x]?fa[x]=getfa(fa[x]):x;}
void init(){
n=read(),q=read();
for (int i=; i<=n; ++i) Insert(root[i],read(),i);
while(q--){
r int x=getfa(read()),y=getfa(read()); if (x==y) continue;
if (root[x]->sz<root[y]->sz) merge(root[x],root[y]),fa[x]=y;
else merge(root[y],root[x]),fa[y]=x;
}
}
void solve(){
q=read();while (q--){
r char op=getchar();while(op!='Q'&&op!='B') op=getchar();
r int x=read(),y=read();
if (op=='Q') printf("%d\n",query(root[getfa(x)],y));
else{
x=getfa(x),y=getfa(y); if (x==y) continue;
if (root[x]->sz<root[y]->sz) merge(root[x],root[y]),fa[x]=y;
else merge(root[y],root[x]),fa[y]=x;
}
}
}
int main(){init(); solve(); return ;}

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

  1. bzoj2733: [HNOI2012]永无乡 启发式合并

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 题目: 2733: [HNOI2012]永无乡 Time Limit: 10 Sec   ...

  2. bzoj2733: [HNOI2012]永无乡(splay)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3778  Solved: 2020 Description 永 ...

  3. [Bzoj2733][Hnoi2012] 永无乡(BST)(Pb_ds tree)

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

  4. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  5. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  6. [BZOJ2733] [HNOI2012] 永无乡 (splay启发式合并)

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

  7. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

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

  8. bzoj2733: [HNOI2012]永无乡 线段树合并

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

  9. BZOJ2733: [HNOI2012]永无乡(线段树合并)

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

  10. BZOJ2733 [HNOI2012]永无乡

    直接平衡树启发式合并就好了...貌似是个很高端的东西.. 貌似可以证明splay的启发式合并是均摊$O(nlogn)$的...而其他平衡树都不行,所以其他的复杂度都是$O(nlog^2n)的$的 所以 ...

随机推荐

  1. 第七次作业:Beta阶段综合报告(Java-Team)

    团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://github.com/WHUSE201 ...

  2. alpha冲刺总结随笔

    前言:前面乱乱糟糟整了一路,到最后终于可以稳定下来了.安安心心做个总结,然后把之后要做的事情都理清楚好了. 新学长似乎是个正经[并不]大腿. 看起来也不用都是一个人或者跟陈华学长两个人对半开了[突然摸 ...

  3. tornado httpserver

    # coding:utf-8 import tornado.web import tornado.ioloop import tornado.httpserver # 新引入httpserver模块 ...

  4. Linux学习--线程概念

    线程 我们知道 ,进程在各自独立的地址空间中运行,进程之间共享数据需要用mmap或者进程间通信机制,本节我们学习如何在一个进程的地址空间中执行多个线程.有些情况需要在一个进程中同时执行多个控制流程,这 ...

  5. Django 博客

    blogproject/blogproject/settings.py ## 其它配置代码... # 把英文改为中文 LANGUAGE_CODE = 'zh-hans' # 把国际时区改为中国时区 T ...

  6. 第二篇:利用shell脚本执行webservice请求——基于soap

    1. 项目背景 以往我们在开发基于webservice的项目中,我们总习惯于直接使用webservice的一些框架,如Axis,axis2和Xfire等.框架的好处是将webservice所涉及到的s ...

  7. java异常常见面试问题

    java异常常见面试问题 一.java异常的理解 异常主要是处理编译期不能捕获的错误.出现问题时能继续顺利执行下去,而不导致程序终止,确保程序的健壮性. 处理过程:产生异常状态时,如果当前的conte ...

  8. 20170222==(MODBUS读取多个寄存器)

    MODBUS读取多个寄存器(功能码04) 为了简单我这里只用4个寄存器,当让你也可以用125个寄存器,但是最多也只能用125个寄存器的.每个寄存器有上面的表知道为一个字的大小即2个字节或者叫16比特位 ...

  9. WebApi 接口返回值类型详解 ( 转 )

    使用过Webapi的园友应该都知道,Webapi的接口返回值主要有四种类型 void无返回值 IHttpActionResult HttpResponseMessage 自定义类型 此篇就围绕这四块分 ...

  10. Mock API是如何在开发中发光发热的?

    在长期的服务过程中,我们经常会遇到前来咨询的用户与我们反馈以下这种情况:咨询者是一个前端人员,在项目开发的过程中需要与后端进行对接,遇到后端还没完成数据输出的情况下,他只好写静态模拟数据,在遇到大型项 ...