【HNOI2012】永无乡 题解(并查集+线段树合并)
给定一张含$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】永无乡 题解(并查集+线段树合并)的更多相关文章
- bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)
[HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...
- [BZOJ2733] [HNOI2012]永无乡(并查集 + 线段树合并)
传送门 一看到第k大就肯定要想到什么权值线段树,主席树,平衡树之类的 然后就简单了 用并查集判断连通,每个节点建立一颗权值线段树,连通的时候直接合并即可 查询时再二分递归地查找 时间复杂度好像不是很稳 ...
- BZOJ- 2733: 永无乡 (并查集&线段树合并)
题意:给定N个节点,K次操作,操作有两种,1是合并两个集合,2是求某个集合的第K大(从小到大排序). 思路:合并只要启发式即可.此题可以用线段树,保存1到N的排序的出现次数和. 复杂度O(NlogN) ...
- bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】
bzoj上数组开大会T-- 本来想用set瞎搞的,想了想发现不行 总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪 ...
- P3224 [HNOI2012]永无乡 题解
P3224 [HNOI2012]永无乡 题解 题意概括 有若干集合,每个集合最初包含一个值,和一个编号1~n.两个操作:合并两个集合,查询包含值x的集合中第k大值最初的集合编号. 思路 维护集合之间关 ...
- BZOJ 3910 并查集+线段树合并
思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...
- BZOJ2733 [HNOI2012]永无乡(并查集+线段树合并)
题目大意: 在$n$个带权点上维护两个操作: 1)在点$u,v$间连一条边: 2)询问点$u$所在联通块中权值第$k$小的点的编号,若该联通块中的点的数目小于$k$,则输出$-1$: 传送门 上周的模 ...
- [HNOI2012] 永无乡 题解
题意: n个点,有加边操作,询问与某一点处于相同的联通块的点中权值第k大的点 思路: 对所有点建立一棵权值线段树,加边就配合并查集进行线段树合并 反思: 动态开点,权值线段树要用sum[g[x=fin ...
- Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G题, 并查集 + 线段树合并)
题目链接 2016 ACM-ICPC EC-Final Problem G 题意 给定一个无向图.每个点有一种颜色. 现在给定$q$个询问,每次询问$x$和$w$,求所有能通过边权值不超过$w$的 ...
随机推荐
- 一题搞定static关键字
基础不牢,地动山摇 开篇一道题,考察代码执行顺序: public class Parent { static { System.out.println("Parent static init ...
- Form表单,textarea标签输入框 字数限制,和已输入字数的统计显示
<script type="text/javascript"> $(document).ready(function() { <%-- 页面进来时就调用 --%& ...
- 【python】Anaconda4 linux/windos安装
一.什么是Anaconda 二.Win10 安装Anaconda 三.Linu 安装Anaconda ------------------------------------------------- ...
- node+express+static完成简单的文件下载
不多说什么,直接上代码 var express = require('express'); var fs = require('fs') var path= require('path'); var ...
- Scala 基础(二):sbt介绍与构建Scala项目
一.sbt简介 sbt是类似ANT.MAVEN的构建工具,全称为Simple build tool,是Scala事实上的标准构建工具. 主要特性: 原生支持编译Scala代码和与诸多Scala测试框架 ...
- 数据可视化之PowerQuery篇(十三)Power BI总计行错误,这个技巧一定要掌握
https://zhuanlan.zhihu.com/p/102567707 前一段介绍过一个客户购买频次统计的案例: Power BI 数据分析应用:客户购买频次分布. 我并没有在文章中显示总计行 ...
- 改造 layui 表格组件实现多重排序
layui 的表格组件目前只支持单列排序,在实际应用中并不能很好的支撑我们的业务需求.今天一时手痒,决定改造一番以支持多重排序. 实现思路也比较简单,只需要用一个数组来存放所有排序的列,再把这个数组传 ...
- 什么是A站、B站、C站、D站、E站、F站、G站、HIJKLM站N站?
A站AcFun弹幕视频网,简称“A站”,成立于2007年6月,取意于Anime Comic Fun,是中国大陆第一家弹幕视频网站.A站以视频为载体,逐步发展出基于原生内容二次创作的完整生态,拥有高质量 ...
- Go Pentester - HTTP Servers(1)
HTTP Server Basics Use net/http package and useful third-party packages by building simple servers. ...
- mybatis自动生成代码插件mybatis-generator使用流程(亲测可用)
mybatis-generator是一款在使用mybatis框架时,自动生成model,dao和mapper的工具,很大程度上减少了业务开发人员的手动编码时间 坐着在idea上用maven构建spri ...