P3224 [HNOI2012]永无乡 题目描述 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛.如果从岛 \(a\) 出发经过若干座(含 \(0\) 座)桥可以 到达岛 \(b\) ,则称岛 \(a\) 和岛 \(b\) 是连通的. 现在有两种操作: B x y 表示在岛 \(x\) 与岛 \(y\…
题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛.如果从岛 aaa 出发经过若干座(含 000 座)桥可以 到达岛 bbb ,则称岛 aaa 和岛 bbb 是连通的. 现在有两种操作: B x y 表示在岛 xxx 与岛 yyy 之间修建一座新桥. Q x k 表示询问当前与岛 xxx 连通的所有岛中第 kkk 重要…
题面 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 \(n\) 座岛排名,名次用 \(1\) 到 \(n\) 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛.如果从岛 \(a\) 出发经过若干座(含 \(0\) 座)桥可以 到达岛 \(b\) ,则称岛 \(a\) 和岛 \(b\) 是连通的. 现在有两种操作: B x y 表示在岛 \(x\) 与岛 \(y\) 之间修建一座新桥. Q x k 表示询问…
题目大意:给你$n$个点,每个点有权值$k$,现有两种操作: 1. $B\;x\;y:$将$x,y$所在联通块合并2. $Q\;x\;k:$查询第$x$个点所在联通块权值第$k$小是哪个数 题解:线段树合并,权值线段树上二分即可 卡点:无 C++ Code: #include <cstdio> #include <cctype> namespace __IO { namespace R { int x, ch; inline int read() { ch = getchar();…
传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)…
题目链接:https://www.luogu.org/problemnew/show/P3224#sub 题目: 题目大意: 维护多个联通块,没有删除操作,每次询问某一联通块的第k大 解法: 维护联通块我们用并查集,询问第k大用splay,合并的时候splay暴力启发式合并就是了 启发式合并:把size小的splay合并到size大的splay上,暴力插入就好了 这道题的具体做法就是我们记录rt数组表示每个点的splay的根,在每次连边的时候就是把一方的根的所有节点全部插入到另一方的根去 其他的…
题目大意:给定 N 个点的图,点有点权,初始有一些无向边,现在有 Q 个询问,每个询问支持动态增加一条无向边连接两个不连通的点和查询第 X 个点所在的联通块中权值第 K 大的是哪个点. 题解:学会了平衡树的启发式合并. 以每个点建立一棵平衡树,需要加边时则合并两个点对应的平衡树,启发式的思想在于合并的时候将 size 小的平衡树信息合并到 size 大的树上.这样,对于每一个被合并的点来说,其所在的平衡树的大小必定翻倍,而最极端的话,所有的点都在一个平衡树中,size = n,因此,每个点被合并…
题目链接 查找排名为k的数用平衡树 合并时用启发式合并,把size小的树上的所有节点插入到size大的树中,每个节点最多需要O(logn)时间 并查集维护连通关系即可 O(nlogn*insert time) 据(主席)说按顺序插入能做到均摊O(1),中序遍历即可有序插入 1.并查集与平衡树是独立的!不要混用fa!并查集只起判断连通关系的作用 2.不需要记录root,Splay时到fa[x]=0即可,因为合并是在一棵树中插入 3.Splay中条件! Update(18.10.2):Splay支持…
题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; ,maxm=maxn,maxq=(3e5)+; ,Q,ans,belong[maxn]; char c; inline int getf(int x){ if(fa[x]==x)return fa[x…
P3224 [HNOI2012]永无乡 题解 题意概括 有若干集合,每个集合最初包含一个值,和一个编号1~n.两个操作:合并两个集合,查询包含值x的集合中第k大值最初的集合编号. 思路 维护集合之间关系显然用并查集,但怎么处理询问,如果只是问最大值,那么显然可以用线段树把最大值存在并查集的祖先上,当然线段树也行.但这里问的是第k大.主席树?主席树是用来处理区间第k大的,而这里每棵树显然储存一整个集合(由多个小集合合并来的)的信息,我们并不关心这个集合内的区间问题,主席树便有点大材小用.所以,得出…