zoukankan      html  css  js  c++  java
  • luogu2633 Count on a tree

    主席树放到树上而已

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n, m, lstans, uu, vv, a[100005], b[100005], rnk[100005], rem, cnt;
    int lson[2200005], rson[2200005], sum[2200005], rot[100005], qwq, ww;
    int fa[100005][19], dep[100005], hea[100005], tt[5];
    struct Edge{
    	int too, nxt;
    }edge[200005];
    void add_edge(int fro, int too){
    	edge[++qwq].nxt = hea[fro];
    	edge[qwq].too = too;
    	hea[fro] = qwq;
    }
    int build(int l, int r){
    	int rt=++cnt;
    	int mid=(l+r)>>1;
    	if(l==r)	return rt;
    	if(l<=mid)	lson[rt] = build(l, mid);
    	if(mid<r)	rson[rt] = build(mid+1, r);
    	return rt;
    }
    int update(int pre, int l, int r, int x){
    	int rt=++cnt;
    	int mid=(l+r)>>1;
    	lson[rt] = lson[pre]; rson[rt] = rson[pre]; sum[rt] = sum[pre] + 1;
    	if(l<r){
    		if(x<=mid)	lson[rt] = update(lson[pre], l, mid, x);
    		if(mid<x)	rson[rt] = update(rson[pre], mid+1, r, x);
    	}
    	return rt;
    }
    void dfs(int x, int f){
    	fa[x][0] = f;
    	dep[x] = dep[f] + 1;
    	rot[x] = update(rot[f], 1, rem, rnk[x]);
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(t!=f)	dfs(t, x);
    	}
    }
    int getLca(int uu, int vv){
    	if(dep[uu]<dep[vv])	swap(uu, vv);
    	for(int i=16; i>=0; i--)
    		if(dep[fa[uu][i]]>=dep[vv])
    			uu = fa[uu][i];
    	if(uu==vv)	return vv;
    	for(int i=16; i>=0; i--)
    		if(fa[uu][i]!=fa[vv][i]){
    			uu = fa[uu][i];
    			vv = fa[vv][i];
    		}
    	return fa[uu][0];
    }
    int query(int l, int r, int k){
    	int tmp=0;
    	int mid=(l+r)>>1;
    	tmp -= sum[lson[tt[3]]] + sum[lson[tt[4]]];
    	tmp += sum[lson[tt[1]]] + sum[lson[tt[2]]];
    	if(l==r)	return l;	
    	if(k<=tmp){
    		for(int i=1; i<=4; i++)
    			tt[i] = lson[tt[i]];
    		return query(l, mid, k);
    	}
    	else{
    		for(int i=1; i<=4; i++)
    			tt[i] = rson[tt[i]];
    		return query(mid+1, r, k-tmp);
    	}
    }
    int main(){
    	cin>>n>>m;
    	for(int i=1; i<=n; i++){
    		scanf("%d", &a[i]);
    		b[i] = a[i];
    	}
    	for(int i=1; i<n; i++){
    		scanf("%d %d", &uu, &vv);
    		add_edge(uu, vv);
    		add_edge(vv, uu);
    	}
    	sort(b+1, b+1+n);
    	rem = unique(b+1, b+1+n) - (b + 1);
    	for(int i=1; i<=n; i++)
    		rnk[i] = lower_bound(b+1, b+1+rem, a[i]) - b;
    	rot[0] = build(1, rem);
    	dfs(1, 0);
    	for(int i=1; i<=16; i++)
    		for(int j=1; j<=n; j++)
    			fa[j][i] = fa[fa[j][i-1]][i-1];
    	while(m--){
    		scanf("%d %d %d", &uu, &vv, &ww);
    		uu ^= lstans;
    		int lca=getLca(uu, vv);
    		tt[1] = rot[uu]; tt[2] =rot[vv];
    		tt[3] = rot[lca]; tt[4] = rot[fa[lca][0]];
    		lstans = b[query(1, rem, ww)];
    		printf("%d
    ", lstans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    后缀数组
    网络流 HOJ1087
    备用
    css-具有缩略图的材料列表
    正则匹配log行
    vue-cli的webpack打包,icon无法正确加载
    导出CSV,导出excel数字过长显示科学计数法解决方案
    js导出CSV
    git常见操作指令
    javascript原型的意义
  • 原文地址:https://www.cnblogs.com/poorpool/p/8334141.html
Copyright © 2011-2022 走看看