题目链接

给定一张含$n$个点$m$条边的无向图,每个点有一个重要指数$a_i$。有两种操作:1.在$x$和$y$之间连一条边;2.求$x$所在连通块中重要程度第$k$小的点。

---------------------------------

维护第$k$小,很容易想到权值线段树。看到合并二字,可以想到用线段树合并的方法。维护连通块可以用并查集做。

注意并查集合并的方向和线段树合并的方向要一致。查询的时候要先找出并查集的根再查询。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,q,fa[],id[],rt[],tot;
struct node
{
int ls,rs,sum;
}tree[];
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline int find(int x)
{
if (x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
inline int build(int index,int l,int r,int pos,int idx)
{
if (!index) index=++tot;
if (l==r){id[index]=idx;tree[index].sum++;return index;}
int mid=(l+r)>>;
if (pos<=mid) tree[index].ls=build(tree[index].ls,l,mid,pos,idx);
else tree[index].rs=build(tree[index].rs,mid+,r,pos,idx);
tree[index].sum=tree[tree[index].ls].sum+tree[tree[index].rs].sum;
return index;
}
inline int merge(int x,int y,int l,int r)
{
if (!x) return y;
if (!y) return x;
if (l==r){if (id[y]){id[x]=id[y];tree[x].sum+=tree[y].sum;}return x;}
int mid=(l+r)>>;
tree[x].ls=merge(tree[x].ls,tree[y].ls,l,mid);
tree[x].rs=merge(tree[x].rs,tree[y].rs,mid+,r);
tree[x].sum=tree[tree[x].ls].sum+tree[tree[x].rs].sum;
return x;
}
inline int query(int index,int x,int l,int r)
{
if (tree[index].sum<x||!index) return ;
if (l==r) return id[index];
int mid=(l+r)>>,ans;
if (x<=tree[tree[index].ls].sum) ans=query(tree[index].ls,x,l,mid);
else ans=query(tree[index].rs,x-tree[tree[index].ls].sum,mid+,r);
return ans;
}
int main()
{
n=read(),m=read();
for (int i=;i<=n;i++)
{
fa[i]=i;int x=read();
rt[i]=build(rt[i],,n,x,i);
}
for (int i=;i<=m;i++)
{
int x=read(),y=read();
x=find(x),y=find(y);
fa[y]=x;
rt[x]=merge(rt[x],rt[y],,n);
}
q=read();
while(q--)
{
char c;cin>>c;
int x=read(),y=read();
if (c=='B')
{
x=find(x),y=find(y);
if (x==y) continue;
fa[y]=x;
rt[x]=merge(rt[x],rt[y],,n);
}
else
{
x=find(x);
int ans=query(rt[x],y,,n);
if (!ans) printf("-1\n");
else printf("%d\n",ans);
}
}
return ;
}

【HNOI2012】永无乡 题解(并查集+线段树合并)的更多相关文章

  1. bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)

    [HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...

  2. [BZOJ2733] [HNOI2012]永无乡(并查集 + 线段树合并)

    传送门 一看到第k大就肯定要想到什么权值线段树,主席树,平衡树之类的 然后就简单了 用并查集判断连通,每个节点建立一颗权值线段树,连通的时候直接合并即可 查询时再二分递归地查找 时间复杂度好像不是很稳 ...

  3. BZOJ- 2733: 永无乡 (并查集&线段树合并)

    题意:给定N个节点,K次操作,操作有两种,1是合并两个集合,2是求某个集合的第K大(从小到大排序). 思路:合并只要启发式即可.此题可以用线段树,保存1到N的排序的出现次数和. 复杂度O(NlogN) ...

  4. bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】

    bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...

  5. P3224 [HNOI2012]永无乡 题解

    P3224 [HNOI2012]永无乡 题解 题意概括 有若干集合,每个集合最初包含一个值,和一个编号1~n.两个操作:合并两个集合,查询包含值x的集合中第k大值最初的集合编号. 思路 维护集合之间关 ...

  6. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  7. BZOJ2733 [HNOI2012]永无乡(并查集+线段树合并)

    题目大意: 在$n$个带权点上维护两个操作: 1)在点$u,v$间连一条边: 2)询问点$u$所在联通块中权值第$k$小的点的编号,若该联通块中的点的数目小于$k$,则输出$-1$: 传送门 上周的模 ...

  8. [HNOI2012] 永无乡 题解

    题意: n个点,有加边操作,询问与某一点处于相同的联通块的点中权值第k大的点 思路: 对所有点建立一棵权值线段树,加边就配合并查集进行线段树合并 反思: 动态开点,权值线段树要用sum[g[x=fin ...

  9. Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G题, 并查集 + 线段树合并)

    题目链接  2016 ACM-ICPC EC-Final Problem G 题意  给定一个无向图.每个点有一种颜色. 现在给定$q$个询问,每次询问$x$和$w$,求所有能通过边权值不超过$w$的 ...

随机推荐

  1. 数据分析02 /pandas基础

    数据分析02 /pandas基础 目录 数据分析02 /pandas基础 1. pandas简介 2. Series 3. DataFrame 4. 总结: 1. pandas简介 numpy能够帮助 ...

  2. 老司机带你玩转面试(3):Redis 高可用之主从模式

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  3. js获取div对象几何信息

    /** * @description 获取对象信息: * bottom: 208 * height: 200 (老版本IE不兼容) * width: 200 (老版本IE不兼容) * left: 8 ...

  4. CSS文本溢出,显示省略号(...)

    方式1:这种方式就是必须要跟width搭配使用,当你使用的display:flex; 的时候可能会影响样式 width: 200px; overflow: hidden; /*超出部分隐藏*/ tex ...

  5. 在ShareX里添加流浪图床

    这里以咱流浪图床为例哈:-D 上传目标类型:图像.文件 请求方法:POST 请求URL:https://p.sda1.dev/api/v1/upload_external_noform URL参数:名 ...

  6. CSS把容器中的内容限制行数,在超过行数后,在最后一行显示"..."

    <style type="text/css"> .main{ width: 400px; background-color: #3498db; display: -we ...

  7. 深入了解PHP的生成器

    在驾驶方面,速度并不会决定一切.但是在网络上,速度至关重要.你的应用程序越快,用户体验就越好.好吧,这时候有人就奇怪了,本文是关于PHP 生成器的,那么为什么我们要谈论速度呢?很快你就会发现,生成器在 ...

  8. 题解 洛谷 P5324 【[BJOI2019]删数】

    先考虑对于一个序列,能使其可以删空的的修改次数. 首先可以发现,序列的排列顺序是没有影响的,所以可以将所有数放到桶里来处理. 尝试对一个没有经过修改的可以删空的序列来进行删数,一开始删去所有的\(n\ ...

  9. Arrays.sort() ----- TimSort

    Arrays.sort() Arrays.sort()对于基本类型使用的是DualPivotQuicksort双轴快速排序,而对于非基本类型使用的是TimSort,一种源自合并排序和插入排序的混合稳定 ...

  10. Android 文件存储浅析

    最近做的一个需求和文件存储有关系.由于之前没有系统梳理过,对文件存储方面的知识一直很懵懂.趁着周末有时间,赶紧梳理一波. 这首从网上找到的一张图,很好的概括了外部存储和内部存储. 下面我们再来具体介绍 ...