• BZOJ 2588


    传送门

    题目分析

    类似于区间型的主席树,树上的主席树也能通过前缀的和差来计算指定路径。
    建立主席树时,子节点从父节点更新,表示从根节点到该子节点的路径线段树(存放节点权值),则若要提取指定路径u->v, 先计算lca, 该路径即为u + v - lca(u, v) - fa(lca(u, v)),其余就没什么难点了。

    wa了半天,原来是lca写错了!!

    code

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 101000, M = 101000;
    int n, m, val[N], b[N], len, fa[N][25], dep[N], dfn[N], clk;
    int ecnt, adj[N], go[M << 1], nxt[M << 1];
    typedef long long ll;
    
    struct node{
    	int lc, rc, cnt;
    }tr[N * 25];
    int pool, rt[N];
    
    namespace IO{
    	inline int read(){
    	    int i = 0, f = 1; char ch = getchar();
    	    for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
    	    if(ch == '-') f = -1, ch = getchar();
    	    for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch -'0');
    	    return i * f;
    	}
    
    	inline void wr(int x){
    		if(x < 0) putchar('-'), x = -x;
    		if(x > 9) wr(x / 10);
    		putchar(x % 10 + '0');
    	}
    }using namespace IO;
    
    inline void addEdge(int u, int v){
    	nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v;
    	nxt[++ecnt] = adj[v], adj[v] = ecnt, go[ecnt] = u;
    }
    
    inline void dfs(int u, int f){
    	dep[u] = dep[f] + 1;
    	dfn[u] = ++clk;
    	fa[u][0] = f;
    	for(int i = 1; i <= 20; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    	for(int e = adj[u], v; e ; e = nxt[e]){
    		if((v = go[e]) == f) continue;
    		dfs(v, u);
    	}
    }
    
    inline int lca(int x, int y){
    	if(dep[x] < dep[y]) swap(x, y);
    	int delta = dep[x] - dep[y];
    	for(int i = 20; i >= 0; i--) if(1 << i & delta) x = fa[x][i]; 
    	if(x == y) return x;
    	for(int i = 20; i >= 0; i--)
    		if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    	return fa[x][0];
    }
    
    inline void disc_init(){
    	sort(b + 1, b + len + 1);
    	len = unique(b + 1, b + len + 1) - b - 1;
    	for(int i = 1; i <= n; i++) val[i] = lower_bound(b + 1, b + len + 1, val[i]) - b;
    }
    
    inline void insert(int x, int &y, int l, int r, int v){
    	tr[y = ++pool] = tr[x];
    	tr[y].cnt++;
    	if(l == r) return;
    	int mid = l + r >> 1;
    	if(v <= mid) insert(tr[x].lc, tr[y].lc, l, mid, v);
    	else insert(tr[x].rc, tr[y].rc, mid + 1, r, v);
    }
    
    inline void tree_init(int u, int f){
    	insert(rt[dfn[f]], rt[dfn[u]], 1, len, val[u]);
    	for(int e = adj[u], v; e; e = nxt[e]){
    		if((v = go[e]) == f) continue;
    		tree_init(v, u);
    	}
    }
    
    inline int query(int u, int v, int w, int x, int l, int r, int k){
    	if(l == r) return l;
    	int delta = tr[tr[u].lc].cnt + tr[tr[v].lc].cnt - tr[tr[w].lc].cnt - tr[tr[x].lc].cnt;
    	int mid = l + r >> 1;
    	if(delta >= k) return query(tr[u].lc, tr[v].lc, tr[w].lc, tr[x].lc, l, mid, k);
    	else return query(tr[u].rc, tr[v].rc, tr[w].rc, tr[x].rc, mid + 1, r, k - delta);
    }
    
    int main(){
    	//freopen("h.in", "r", stdin);
    	n = read(), m = read();
    	for(int i = 1; i <= n; i++) val[i] = b[++len] = read();
    	disc_init();
    	for(int i = 1; i < n; i++){
    		int x = read(), y = read();
    		addEdge(x, y);
    	}
    	dfs(1, 0);
    	tree_init(1, 0);
    	int ans = 0;
    	for(int i = 1; i <= m; i++){
    		int u = read() ^ ans, v = read(), k = read();
    		int LCA = lca(u, v);
    		int w = rt[dfn[LCA]], x = rt[dfn[fa[LCA][0]]];
    		u = rt[dfn[u]], v = rt[dfn[v]];
    		
    		ans = b[query(u, v, w, x, 1, len, k)];
    		wr(ans);
    		if(i < m) putchar('
    ');
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    asp.net Ajax调用Aspx后台方法
    JS 通过字符串取得对应对象
    nginx js、css、图片 及 一些静态文件中出现 http://upstreamname:port 导致部分网页样式显示不正常
    jexus手动跨域设置
    HTTP Error 400. The request hostname is invalid
    at MySql.Data.MySqlClient.MySqlStream.ReadPacket 或 FUNCTION account.AddMinutes does not exist
    sql xml 入门
    Jexus .Net at System.Net.Sockets.Socket.Connect (System.Net.IPAddress[] addresses, System.Int32 port)
    关于SQL SERVER中的FLOAT转换为VARCHAR
    JS倒计时
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7646981.html
Copyright © 2020-2023  润新知