1 条题解

  • 0
    @ 2026-7-3 16:56:48

    要维护集合中第 k 大的元素,注意到 k 最大为 10,我们可以用set维护一个集合内前10大的元素 查询时答案就为倒数第 k 个元素,代码如下:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N = 2e5 + 10;
    int fa[N];
    set<int> rk[N]; // 维护集合中前 10 大的节点编号 
    int find(int x) {
    	return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    
    void merge(int x, int y) {
    	int fx = find(x), fy = find(y);
    	if (fx != fy) {
    		fa[fx] = fy;
    		rk[fy].insert(rk[fx].begin(), rk[fx].end()); // 合并
    		rk[fx].clear(); // 节省空间
    		while (rk[fy].size() > 10) rk[fy].erase(rk[fy].begin()); // 维护大小保持在 10,删除更小的元素 
    	}
    }
    
    int main() {
    	int n, q;
    	cin >> n >> q;
    	
    	for (int i = 1; i <= n; i++) {
    		fa[i] = i;
    		rk[i].insert(i);
    	}
    	
    	int opt, u, v, k;
    	for (int i = 1; i <= q; i++) {
    		cin >> opt;
    		if (opt == 1) {
    			cin >> u >> v;
    			merge(u, v);
    		} else {
    			cin >> v >> k;
    			
    			int fv = find(v);
    			
    			if (rk[fv].size() < k) cout << "-1\n";
    			else {
    				auto it = next(rk[fv].rbegin(), k - 1); // 搜索倒数第 k 个元素,即第 k 大的元素
    				cout << *it << "\n";
    			}
    		}
    	}
    
    	return 0;
    }
    
    
    • 1

    [ABC372E] K-th Largest Connected Components

    信息

    ID
    7947
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    4
    已通过
    3
    上传者