• Luogu P2633 Count on a tree


    [题目链接 (Click) (Here)](P2633 Count on a tree)

    树上建主席树,方法和序列上相差不多。就是被最大值卡(RE)好几次。。。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 100010;
    #define int long long
    
    int n, m, cnt, val[N], head[N];
    
    struct edge {
    	int nxt, to;
    	edge (int _nxt = 0, int _to = 0) {
    		nxt = _nxt, to = _to;
    	}
    }e[N << 1];
    
    void add_len (int u, int v) {
    	e[++cnt] = edge (head[u], v); head[u] = cnt;
    	e[++cnt] = edge (head[v], u); head[v] = cnt;
    }
    
    int tot, rt[N];
    
    struct Segment_Node {
    	int ls, rs, sz;
    }t[N << 7];
    
    #define mid ((l + r) >> 1)
    
    int modify (int _rt, int l, int r, int w) {
    	int p = ++tot;
    	t[p].sz = t[_rt].sz + 1;
    	if (l != r) {
    		if (w <= mid) {
    			t[p].ls = modify (t[_rt].ls, l, mid, w), t[p].rs = t[_rt].rs;
    		} else {
    			t[p].rs = modify (t[_rt].rs, mid + 1, r, w), t[p].ls = t[_rt].ls;
    		}
    	} else {
    		t[p].ls = t[p].rs = 0;
    	}
    	return p;
    }
    
    int deep[N], fa[N][21];
    
    void dfs (int u, int _fa) {
    	fa[u][0] = _fa;
    	deep[u] = deep[_fa] + 1;
    	rt[u] = modify (rt[_fa], 0, 1e10, val[u]);
    	for (int i = 1; (1 << i) <= deep[u]; ++i) {
    		fa[u][i] = fa[fa[u][i - 1]][i - 1];
    	}
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (v != _fa) {
    			dfs (v, u);
    		}
    	}
    } 
    
    int lca (int u, int v) {
    	if (deep[u] < deep[v]) swap (u, v);
    	for (int i = 20; i >= 0; --i) {
    		if (deep[u] - (1 << i) >= deep[v]) {
    			u = fa[u][i];
    		}
    	}
    	if (u == v) return u;
    	for (int i = 20; i >= 0; --i) {
    		if (fa[u][i] != fa[v][i]) {
    			u = fa[u][i];
    			v = fa[v][i];
    		}
    	}
    	return fa[u][0];
    }
    
    int query (int u, int v, int k) {
    	int _lca = lca (u, v);
    	int l1 = rt[_lca], r1 = rt[v];
    	int l2 = rt[fa[_lca][0]], r2 = rt[u];
    	int l = 0, r = 1e10;
    	while (l < r) {
    		int lch = 0;
    		lch += t[t[r1].ls].sz - t[t[l1].ls].sz;
    	    lch += t[t[r2].ls].sz - t[t[l2].ls].sz;
    		if (k <= lch) {
    			l1 = t[l1].ls, r1 = t[r1].ls;
    			l2 = t[l2].ls, r2 = t[r2].ls;
    			r = mid;
    		} else {
    			l1 = t[l1].rs, r1 = t[r1].rs;
    			l2 = t[l2].rs, r2 = t[r2].rs;
    			l = mid + 1;
    			k -= lch;
    		}
    	}
    	return r;
    }
    
    signed main () {
    	// freopen ("data.in", "r", stdin);
    	t[0].sz = t[0].ls = t[0].rs = 0;
    	cin >> n >> m;
    	for (int i = 1; i <= n; ++i) cin >> val[i];
    	for (int i = 1; i <= n - 1; ++i) {
    		static int u, v;
    		cin >> u >> v;
    		add_len (u, v);
    	}
    	dfs (1, 0);
    	for (int i = 1; i <= m; ++i) {
    		static int u, v, k, last_ans;
    		cin >> u >> v >> k;
    		u ^= last_ans;
    		last_ans = query (u, v, k);
    		cout << last_ans << endl;
    	}
    } 
    
    
  • 相关阅读:
    javascript无提示关闭窗口,兼容IE,Firefox
    vbs简单制作U灵大盗带发送功能的代码
    正则表达式提取网址、标题、图片等一例(.Net Asp Javascript/Js)的实现
    在asp.net中保持Session的有效期
    批处理编程 介绍
    IIS日志清理CMD版,VBS版,JS版,WSH版
    正则表达式提取图片地址
    用U盘安装GNU/Linux
    三核浏览器Lunascape新版发布
    黑客基础之DOS(最齐全)
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10538953.html
Copyright © 2020-2023  润新知