• [LUOGU]P2633 Count on a tree


    其实和luogu上主席树的板子差不多,就是把它放到了树上,把板子改成求sum[u]+sum[v]-sum[lca]-sum[lcafa]的就行了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=100005;
    struct Edge{int to,nxt;}e[N<<1];
    int tim,dfn1[N],dfn2[N],top[N],son[N],siz[N],fa[N],dep[N],head[N],ecnt,rt[N<<5],a[N],b[N],u,n,m;
    void add(int bg,int ed) {e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
    void dfs(int x) {
    	siz[x]=1;
    	for(int i=head[x];i;i=e[i].nxt) {
    		int v=e[i].to;
    		if(v==fa[x]) continue;
    		fa[v]=x,dep[v]=dep[x]+1;
    		dfs(v);siz[x]+=siz[v];
    		if(siz[v]>siz[son[x]]) son[x]=v;
    	}
    }
    void dfs(int x,int qtop) {
    	top[x]=qtop;dfn1[x]=++tim;
    	if(!son[x]) return;
    	dfs(son[x],qtop);
    	for(int i=head[x];i;i=e[i].nxt) {
    		int v=e[i].to;
    		if(v==son[x]||v==fa[x]) continue;
    		dfs(v,v);
    	}
    	dfn2[x]=tim;
    }
    int ls[N<<5],rs[N<<5],sum[N<<5],tot;
    void build(int &k,int l,int r) {
    	k=++tot;
    	if(l<r) {
    		int mid=l+r>>1;
    		build(ls[k],l,mid);
    		build(rs[k],mid+1,r);
    	}
    }
    void update(int &k,int l,int r,int pre,int c) {
    	ls[k=++tot]=ls[pre],rs[k]=rs[pre],sum[k]=sum[pre]+1;
    	if(l<r) {
    		int mid=l+r>>1;
    		if(c<=mid) update(ls[k],l,mid,ls[pre],c);
    		else update(rs[k],mid+1,r,rs[pre],c);
    	}
    }
    int query(int u,int v,int lca,int lcafa,int l,int r,int kth) {
    	if(l==r) return l;
    	int nowsiz=sum[ls[u]]+sum[ls[v]]-sum[ls[lca]]-sum[ls[lcafa]],mid=l+r>>1;
    	if(nowsiz<kth) return query(rs[u],rs[v],rs[lca],rs[lcafa],mid+1,r,kth-nowsiz);
    	return query(ls[u],ls[v],ls[lca],ls[lcafa],l,mid,kth);
    }
    void chairman(int x) {
    	update(rt[x],1,u,rt[fa[x]],a[x]);
    	for(int i=head[x];i;i=e[i].nxt) {
    		int v=e[i].to;
    		if(v!=fa[x]) chairman(v);
    	}
    }
    int LCA(int x,int y) {
    	while(top[x]!=top[y]) 
    		(dep[top[x]]>=dep[top[y]])?x=fa[top[x]]:y=fa[top[y]];
    	return dep[x]<dep[y]?x:y;
    }
    int lastans;
    int main() {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
    	for(int i=1,x,y;i<n;i++) {
    		scanf("%d%d",&x,&y);
    		add(x,y);add(y,x);
    	}
    	sort(b+1,b+1+n);
    	u=unique(b+1,b+1+n)-b-1;
    	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+u,a[i])-b;
    	build(rt[0],1,u);
    	dfs(1);dfs(1,1);
    	chairman(1);
    	int lca,xx,v,k;
    	while(m--) {
    		scanf("%d%d%d",&xx,&v,&k);
    		xx^=lastans;
    		lca=LCA(xx,v);
    		printf("%d
    ",lastans=b[query(rt[xx],rt[v],rt[lca],rt[fa[lca]],1,u,k)]);
    	}
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    tudou(土豆)、youku(优酷)API(有相应的dll [C#])
    创新工场2012笔试编程捕鱼和分鱼
    区别Web文本框和HTML文本框的RandOnly、Disabled
    DataRow[]、List<DataRow>无法绑定到GridView的问题解决!
    1、NHibernate入门
    Verilog HDL 学习笔记2blocking and nonblocking assignment
    Verilog HDL 学习笔记1data type
    2006.08.21网摘
    推荐十一个很酷的实用网站
    类 ObjectOutputStream的writeObject()方法的中英文对照
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9483814.html
Copyright © 2020-2023  润新知