zoukankan      html  css  js  c++  java
  • 【BZOJ2588】Count On a Tree(主席树)

    • 把1的父亲设成了1导致debug半天
    /*
    惊奇的发现我不会写树上主席树QAQ
    并不是进行链剖, 而是继承父亲, 然后根据主席树的可减性来求解
    求lca可是还是要剖的
    
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #define ll long long
    #define mmp make_pair
    #define M 100010
    using namespace std;
    int read() {
    	int nm = 0, f = 1;
    	char c = getchar();
    	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    	return nm * f;
    }
    int a[M], b[M], c[M], rt[M], fa[M], top[M], sz[M], deep[M], son[M], n, q, cnt, ans;
    vector<int> to[M];
    
    int ls[M * 44], rs[M * 44], t[M * 44];
    
    void dfs(int now, int f) {
    	fa[now] = f;
    	sz[now] = 1;
    	deep[now] = deep[f] + 1;
    	for(int i = 0; i < to[now].size(); i++) {
    		int vj = to[now][i];
    		if(vj == f) continue;
    		dfs(vj, now);
    		sz[now] += sz[vj];
    		if(sz[son[now]] < sz[vj]) son[now] = vj;
    	}
    }
    
    
    void modify(int l, int r, int last, int &now, int k) {
    	now = ++cnt;
    	t[now] = t[last] + 1;
    	ls[now] = ls[last];
    	rs[now] = rs[last];
    	if(l == r) return;
    	int mid = (l + r) >> 1;
    	if(k <= mid) modify(l, mid, ls[last], ls[now], k);
    	else modify(mid + 1, r, rs[last], rs[now], k);
    }
    
    int query(int l, int r, int rt1, int rt2, int rt3, int rt4, int k) {
    	if(l == r) return l;
    	int mid = (l + r) >> 1;
    	int v = t[ls[rt3]] + t[ls[rt4]] - t[ls[rt1]] - t[ls[rt2]];
    	if(k > v) return query(mid + 1, r, rs[rt1], rs[rt2], rs[rt3], rs[rt4], k - v);
    	else return query(l, mid, ls[rt1], ls[rt2], ls[rt3], ls[rt4], k);
    }
    
    void dfs(int now) {
    	modify(1, n, rt[fa[now]], rt[now], a[now]);
    	if(son[now]) {
    		top[son[now]] = top[now];
    		dfs(son[now]);
    	}
    	for(int i = 0; i < to[now].size(); i++) {
    		int vj = to[now][i];
    		if(vj == fa[now] || vj == son[now]) continue;
    		top[vj] = vj;
    		dfs(vj);
    	}
    }
    
    int lca(int a, int b) {
    	for(; top[a] != top[b]; a = fa[top[a]]) {
    		if(deep[top[a]] < deep[top[b]]) swap(a, b);
    	}
    	if(deep[a] > deep[b]) swap(a, b);
    	return a;
    }
    
    int main() {
    	n = read(), q = read();
    	for(int i = 1; i <= n; i++) a[i] = b[i] = read();
    	sort(b + 1, b + n + 1);
    	for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
    	for(int i = 1; i < n; i++) {
    		int vi = read(), vj = read();
    		to[vi].push_back(vj);
    		to[vj].push_back(vi);
    	}
    	dfs(1, 0);
    	top[1] = 1;
    	dfs(1);
    	while(q--) {
    		int vi = read() ^ ans, vj = read(), k = read();
    		int l = lca(vi, vj);
    		ans = b[query(1, n, rt[l], rt[fa[l]], rt[vi], rt[vj], k)];
    		cout << ans << "
    ";
    	}
    	return 0;
    }
    /*
    8 1
    105 2 9 3 8 5 7 7
    1 2
    1 3
    1 4
    3 5
    3 6
    3 7
    4 8
    1 4 4
    */
    
    
  • 相关阅读:
    Ubuntu10.04搭建linux-0.11编译环境(1.bochs安装和使用)
    Linux 0.11内核编译和bochs上的实验环境的搭建
    64位Linux的内核和用户地址空间
    2012年计算机考研大纲——操作系统
    【27.34%】【codeforces 611D】New Year and Ancient Prophecy
    【14.94%】【codeforces 611E】New Year and Three Musketeers
    【53.57%】【codeforces 610C】Harmony Analysis
    【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
    【49.23%】【hdu 1828】Picture
    【20.51%】【codeforces 610D】Vika and Segments
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/10721272.html
Copyright © 2011-2022 走看看