zoukankan      html  css  js  c++  java
  • Luogu3302 [SDOI2013]森林

    题目蓝链

    Description

    给你一个森林,你需要支持两个操作:

    1. 查询一条路径上第(k)小的权值是多少

    2. 连接两个点

    强制在线

    Solution

    我们一开始看到这道题,一定会想什么LCT套主席树 乱编的

    其实我们只需要主席树就可以了。我们发现这题只需要连边,不需要断边。所以我们可以启发式合并,暴力维护较小的那部分的主席树和倍增数组

    时间复杂度(mathcal{O}(n log^2 n))

    如果你还不会用主席树维护链上第(k)大,请右转 传送门

    Solution

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define fst first
    #define snd second
    #define mp make_pair
    #define squ(x) ((LL)(x) * (x))
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    
    typedef long long LL;
    typedef pair<int, int> pii;
    
    template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
    
    inline int read() {
    	int sum = 0, fg = 1; char c = getchar();
    	for (; !isdigit(c); c = getchar()) if (c == '-') fg = -1;
    	for (; isdigit(c); c = getchar()) sum = (sum << 3) + (sum << 1) + (c ^ 0x30);
    	return fg * sum;
    }
    
    const int maxn = 8e4 + 10;
    
    int n, m, q, len;
    int w[maxn], t[maxn];
    vector<int> g[maxn];
    
    int Fa[maxn], sz[maxn];
    inline int find(int x) { return x == Fa[x] ? x : Fa[x] = find(Fa[x]); }
    inline void merge(int x, int y) { x = find(x), y = find(y), Fa[x] = y, sz[y] += x; }
    
    int rt[maxn];
    namespace ST {
    	int cnt;
    	struct node {
    		int ls, rs, v;
    	}A[maxn << 9];
    	void init() { cnt = 0; }
    	void change(int &nrt, int rt, int l, int r, int x) {
    		A[nrt = ++cnt] = A[rt], ++A[nrt].v;
    		if (l == r) return;
    		int mid = (l + r) >> 1;
    		if (x <= mid) change(A[nrt].ls, A[rt].ls, l, mid, x);
    		else change(A[nrt].rs, A[rt].rs, mid + 1, r, x);
    	}
    	int query(int a, int b, int c, int d, int l, int r, int k) {
    		if (l == r) return l;
    		int mid = (l + r) >> 1;
    		int tot = A[A[a].ls].v + A[A[b].ls].v - A[A[c].ls].v - A[A[d].ls].v;
    		if (k <= tot) return query(A[a].ls, A[b].ls, A[c].ls, A[d].ls, l, mid, k);
    		return query(A[a].rs, A[b].rs, A[c].rs, A[d].rs, mid + 1, r, k - tot);
    	}
    }
    
    int d[maxn], fa[maxn][17];
    
    inline int lca(int x, int y) {
    	if (d[x] < d[y]) swap(x, y);
    	for (int i = 16; ~i; i--)
    		if (d[fa[x][i]] >= d[y]) x = fa[x][i];
    	if (x == y) return x;
    	for (int i = 16; ~i; i--)
    		if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    	return fa[x][0];
    }
    
    bool v[maxn];
    inline void dfs(int now, int f) {
    	v[now] = 1, fa[now][0] = f, d[now] = d[f] + 1;
    	for (int i = 1; i <= 16; i++) fa[now][i] = fa[fa[now][i - 1]][i - 1];
    	ST::change(rt[now], rt[f], 1, len, w[now]);
    	for (int son : g[now]) {
    		if (son == f) continue;
    		dfs(son, now);
    	}
    }
    
    int main() {
    #ifdef xunzhen
    	freopen("forest.in", "r", stdin);
    	freopen("forest.out", "w", stdout);
    #endif
    
    	n = read();
    	n = read(), m = read(), q = read();
    
    	for (int i = 1; i <= n; i++) Fa[i] = i, sz[i] = 1;
    
    	for (int i = 1; i <= n; i++) t[i] = w[i] = read();
    	sort(t + 1, t + n + 1);
    	len = unique(t + 1, t + n + 1) - t - 1;
    	for (int i = 1; i <= n; i++) w[i] = lower_bound(t + 1, t + len + 1, w[i]) - t;
    
    	for (int i = 1; i <= m; i++) {
    		int x = read(), y = read();
    		g[x].push_back(y);
    		g[y].push_back(x);
    		merge(x, y);
    	}
    
    	for (int i = 1; i <= n; i++) if (!v[find(i)]) dfs(find(i), 0);
    
    	int lans = 0;
    	for (int i = 1; i <= q; i++) {
    		static char op[10];
    		scanf("%s", op);
    		if (op[0] == 'Q') {
    			int x = read() ^ lans, y = read() ^ lans, k = read() ^ lans, f = lca(x, y);
    			printf("%d
    ", lans = t[ST::query(rt[x], rt[y], rt[f], rt[fa[f][0]], 1, len, k)]);
    		} else {
    			int x = read() ^ lans, y = read() ^ lans;
    			if (sz[x] > sz[y]) swap(x, y);
    			g[x].push_back(y), g[y].push_back(x);
    			merge(x, y), dfs(x, y);
    		}
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    [Intellij] 软件设置和常用快捷键
    [Intellij] Project Structure 配置说明
    [日志log] 常用log日志记录方式对比和详解
    [J2EE]web.xml各个版本模板
    [技术选型] CDH-Cloudera Distribution Hadoop
    [技术选型] dubbo
    [技术选型] spring boot
    [hbase] HBase内置过滤器的一些总结
    [zookeeper] Zookeeper伪分布式集群配置
    [maven] settings 文件 本地maven仓库
  • 原文地址:https://www.cnblogs.com/xunzhen/p/10322505.html
Copyright © 2011-2022 走看看