首页 > 其他分享 >P3224 [HNOI2012] 永无乡

P3224 [HNOI2012] 永无乡

时间:2024-09-20 15:46:31浏览次数:9  
标签:rt return int 永无 tr HNOI2012 P3224 rk size

题意

image

思路

用并查集维护连通性,每个集合维护一个平衡树,每次合并两个集合的时候,将一个平衡树的节点一个一个加入到另一个中。

这么做不会超时,每次将小的平衡树拆掉放到大的中,可以证明不会超过 \(O(\log n)\) 次。

总时间复杂度 \(O(n \log ^ 2 n)\)。

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1000010;

struct node {
	int l, r;
	int size;
	int rnd;
	int key;
	int x;
} tr[N];

int rt[N], idx;

void pushup(int u) {
	tr[u].size = tr[tr[u].l].size + tr[tr[u].r].size + 1;
}

void split(int u, int key, int& x, int& y) {
	if (!u) {
		x = y = 0;
		return;
	}
	if (tr[u].key <= key) {
		x = u;
		split(tr[u].r, key, tr[u].r, y);
	}
	else {
		y = u;
		split(tr[u].l, key, x, tr[u].l);
	}
	pushup(u);
}

int merge(int x, int y) {
	if ((!x) || (!y)) return x | y;
	if (tr[x].rnd < tr[y].rnd) {
		tr[x].r = merge(tr[x].r, y);
		pushup(x);
		return x;
	}
	else {
		tr[y].l = merge(x, tr[y].l);
		pushup(y);
		return y;
	}
}

int newnode(int key, int x) {
	idx++;
	tr[idx].key = key;
	tr[idx].rnd = rand();
	tr[idx].size = 1;
	tr[idx].l = tr[idx].r = 0;
	tr[idx].x = x;
	return idx;
}

void insert(int& rt, int key, int g) {
	int x, y;
	split(rt, key, x, y);
	int z = newnode(key, g);
	rt = merge(merge(x, z), y);
}

int fa[N];

int find(int x) {
	if (x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}

void merge_fa(int x, int y) {
	x = find(x), y = find(y);
	if (x == y) return;
	if (tr[rt[x]].size > tr[rt[y]].size) swap(x, y);
	fa[x] = y;
	
	queue<int> q;
	q.push(rt[x]);
	while (q.size()) {
		int t = q.front();
		q.pop();
		insert(rt[y], tr[t].key, tr[t].x);
		if (tr[t].l) q.push(tr[t].l);
		if (tr[t].r) q.push(tr[t].r);
	}
}

int get_rank(int u, int rk) {
	if (tr[tr[u].l].size + 1 == rk) return tr[u].x;
	if (tr[tr[u].l].size >= rk) return get_rank(tr[u].l, rk);
	return get_rank(tr[u].r, rk - tr[tr[u].l].size - 1);
}

int n, m;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		int x;
		cin >> x;
		insert(rt[i], x, i);
		fa[i] = i;
	}
	
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		merge_fa(u, v);
	}
	int q;
	cin >> q;
	char opt;
	int x, y;
	while (q--) {
		cin >> opt >> x >> y;
		if (opt == 'Q') {
			x = find(x);
			if (tr[rt[x]].size < y) cout << "-1\n";
			else cout << get_rank(rt[x], y) << '\n';
		}
		else merge_fa(x, y);
	}
	return 0;
}

标签:rt,return,int,永无,tr,HNOI2012,P3224,rk,size
From: https://www.cnblogs.com/Yuan-Jiawei/p/18422640

相关文章

  • 永无乡
    考虑在线维护,显然用并查集。对每一个集合都维护一个Splay(或其他平衡树),然后直接查询就好了;所以现在的任务就是合并两个Splay。如果满足一个Splay的最大值小于另一个Splay的最小值,那么是可以快速合并的;但是这里显然不满足,所以只能用启发式合并,对于较小的Splay,遍历其每个节点,然后将每......
  • P3224[HNOI2012]永无乡
    P3224[HNOI2012]永无乡(超详细!)居然没有人写平板电视库的题解(pbdsyyds)不了解pbds库的可以去看oiwiki或者上网学习。题目大意给定一个无向图,询问\(x\)所在连通块排名第\(y\)的点,且带加边修改。刚开始每个点属于一个连通块,\(m\)条边可以看做\(m\)个加边的操作。思......
  • [lnsyoj300/luoguP3224/HNOI2012]永无乡
    题意给定\(n\)个集合,每个集合最开始只包含数\(a_i\),然后进行\(m\)次合并操作。具体地,每次操作将数\(a_i\)所在的集合与数\(a_j\)所在的集合合并。接下来,进行\(q\)次操作,每次操作可能为合并操作与查询操作,合并操作与上述相同,查询操作为查询数\(a_x\)所在的集合中第......
  • [HNOI2012] 矿场搭建 题解
    [HNOI2012]矿场搭建前置知识:#Tarjan求点双连通分量题目大意​ 给你一张无向连通图,任意删去其中一个点,要求在删点后在每个连通块中有一个点被选择,问至少需要选择多少个点,以及选择的方案数。输入输出格式输入​ 多组数据以\(N=0\)结束​ 每组数据第一行为边的数量\(N\(N......
  • P3219 [HNOI2012] 三角形覆盖问题&P1222 三角形 题解
    严格单$\log$做法,附实现细节和代码。考虑从左往右扫描线,发现每次操作是线段上端点$-1$,插入线段,删除退化成点的线段。如果某时刻一条线段被另一条完全覆盖,那么这条线段显然不会产生贡献,可以删去。最后得到的线段一定是左端点单调递增时,右端点也单调递增,可以用set维护。当两......
  • 【题解】HNOI2012 - 集合选数
    HNOI2012-集合选数https://www.luogu.com.cn/problem/P3226不算难的非显然状压dp。首先根据限制条件建图,\((x,2x),(x,3x)\)连边,表示边上相邻两个点不能同时选,然后一组独立集就是一个可行的集合。发现画出来的图是若干个部分网格图,每个连通块最小的点都是与\(6\)互质的数......
  • 佛祖保佑 永无bug 永不宕机
    _ooOoo_o8888888o88"."88(|-_-|)O\=/O____/`---'\____.'\\||//`./\\|||:|||//\......
  • 大型网站技术架构:核心原理与案例分析—第六章:永无止境:网站的伸缩性架构
    1,网站架构的伸缩性设计一般说来,网站的伸缩性设计可分为两类,一类是根据功能进行物理分离实现伸缩;一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相同的功能。1)不同功能进行物理分离实现伸缩每......
  • [HNOI2012] 集合选数
    [HNOI2012]集合选数目录题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示题意概括思路历程:1.设计状态2.设计转移代码实现:题目描述《集合论与图论》这门课程有一道作业题,要求同学们求出\(\{1,2,3,4,5\}\)的所有满足以下条件的子集:若\(x\)在该子集中,则\(2......
  • BZOJ 2730: [HNOI2012]矿场搭建 tarjan割点
    2730:[HNOI2012]矿场搭建TimeLimit: 10Sec  MemoryLimit: 128MBSubmit: 2010  Solved: 935[Submit][Status][Discuss]Description煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口......