https://vjudge.net/problem/HYSBZ-2733

给一些带权点,有些点是互相连通的,

然后给出2种操作,在两点间加一条边,或者询问一个点所在的连通块内的第k小值的编号

并查集辅助+splay的启发式合并就行

由于结构简单,动态开点线段树合并也可以做

我写的是splay,由于一个奇怪的bug,我一气之下把之前的核心代码里的我自己写的splay和rotate代码全换成板子了

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
const int maxn=1e6+10,maxm=2e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
vector<int> pre;
int find(int now) {return pre[now]==now?now:pre[now]=find(pre[now]);}
vector<int> val;
class splaytree{public:
#define nd node[now]
#define ndl node[node[now].son[0]]
#define ndr node[node[now].son[1]]
struct splaynode{
int son[2],fa,val,size;
splaynode(){size=1,fa=son[0]=son[1]=0;}
};
int cnt,root;
vector<splaynode> node;
inline void pushup(int now){nd.size=ndl.size+ndr.size+1;}
inline void pushdown(int now){}
inline int wh(int now){return node[nd.fa].son[1]==now;}
void rotate(int now){
int fa=nd.fa,gf=node[fa].fa,c=wh(now);
pushdown(fa);pushdown(now);
if(gf) node[gf].son[wh(fa)]=now;
nd.fa=gf;
node[fa].son[c]=nd.son[c^1];
node[node[fa].son[c]].fa=fa;nd.son[c^1]=fa;node[fa].fa=now;
pushup(fa);pushup(now);
}
void splay(int now,int dst=0){
for(;nd.fa!=dst;rotate(now))
if(node[nd.fa].fa!=dst)rotate(wh(now)==wh(nd.fa)?nd.fa:now);
if(!dst) root=now;
}
void insert(int pos){
int now=root,fa=0,val=node[pos].val;
while(now) fa=now,now=val<nd.val?nd.son[0]:nd.son[1];
now=pos;
node[fa].son[val>node[fa].val]=now;
nd.fa=fa;
splay(now);
}
void order(int now){
int l=nd.son[0],r=nd.son[1];
nd.son[0]=nd.son[1]=nd.fa=0;
nd.size=1;
if(l) order(l);
insert(now);
if(r) order(r);
}
void merge(int a,int b){
if(a==b) return ;
splay(a);splay(b);
if(node[a].size>node[b].size) swap(a,b);
pre[a]=b;root=b;
order(a);
}
int kth(int now,int k){
splay(now);int lsize=0;
while(now){
int lsum=lsize+ndl.size;
if(k<=lsum) now=nd.son[0];
else if(k==lsum+1) return now;
else lsize=lsum+1,now=nd.son[1];
}
return -1;
}
splaytree(int n){
node.resize(n+7,splaynode());
rep(i,1,n) node[i].val=val[i];
node[0].size=0;
root=0,cnt=0;
}
};
int main() {
IO;
int a,b;
cin>>n>>m;
val.resize(n+2);
pre.resize(n+2);
rep(i,1,n) cin>>val[i],pre[i]=i;
splaytree tree(n);
while(m--) {
cin>>a>>b;
a=find(a),b=find(b);
tree.merge(a,b);
}
cin>>m;string s;
while(m--){
cin>>s>>a>>b;
if(s=="B") {
a=find(a),b=find(b);
tree.merge(a,b);
}else{
a=find(a);
cout<<tree.kth(a,b)<<endl;
}
}
return 0;
}

bzoj2733 永无乡 splay树的启发式合并的更多相关文章

  1. BZOJ2733 永无乡【splay启发式合并】

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

  2. 【BZOJ-2733】永无乡 Splay+启发式合并

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

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

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

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

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

  5. BZOJ2733 永无乡 【splay启发式合并】

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 4190  Solved: 2226 [Submit][Sta ...

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

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

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

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

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

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

  9. 【bzoj2733】[HNOI2012]永无乡 线段树合并

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

随机推荐

  1. OCR技术浅析-无代码篇(1)

    图像识别中最贴近我们生活的可能就是 OCR 技术了. OCR 的定义:OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打 ...

  2. 干货型up主

    很多教学视频,我看了反射,正在看JAVAWEB 和Spring  讲得很清楚 反正就是很好!!! https://space.bilibili.com/326782142?spm_id_from=33 ...

  3. iview table行render渲染不同的组件

    table不同的行,相同的列渲染不同的组件,如图1:第一行渲染selece,第二行渲染input render:(h,params)=>{ if(params.index === 0){ //以 ...

  4. poj2778(AC自动机+矩阵快速幂)

    题意:给你n个字符串,问你长度为m的字符串且字符串中不含有那n个子串的字符串的数量 解题思路:这道题一开始就不太懂,还以为是组合数学的题目,后面看了别人的博客,才知道这是属于AC自动机的另一种用法,是 ...

  5. Luogu5290 十二省联考2019春节十二响(贪心+启发式合并)

    考虑链的做法,显然将两部分各自从大到小排序后逐位取max即可,最后将根计入.猜想树上做法相同,即按上述方式逐个合并子树,最后加入根.用multiset启发式合并即可维护.因为每次合并后较小集合会消失, ...

  6. 洛谷P3806 点分治

    点分治 第一次写点分治..感觉是一个神奇而又暴力的东西orz 点分治大概就是用来处理树上链的信息,把路径分成过点x和不过点x的两种,不过点x的路径可以变成过点x的子树中一点的路径,递归处理 #incl ...

  7. edusoho -A5: AppBundle UML

    edusoho -A5:  AppBundle UML

  8. spring boot junit controller

    MockMvc 来自Spring Test,它允许您通过一组方便的builder类向 DispatcherServlet 发送HTTP请求,并对结果作出断言.请注意,@AutoConfigureMoc ...

  9. 来自多校的一个题——数位DP+卡位

    n<=1e9就要考虑倍增.矩阵乘法这种了 假设L=0 考虑枚举二进制下,所有X与R的LCP长度,前len高位 对于第len+1位,假设R的这一位是1 如果一个x的这一位是0了,那么后面可以随便填 ...

  10. Notepad++ 的函数参数提示错误的问题终于解决了

    看第3张图片,明明我输入的是 print_double(), 提示的却是 print() 函数的参数. 这个问题困扰了我半年,今天晚上找到解决问题的办法: