zoukankan      html  css  js  c++  java
  • 洛谷 P2633 Count on a tree 题解

    题面

    对于每个点建立一颗主席树;

    然后按照树上差分的思想统计主席树的前缀和;

    lca+主席树+前向星存表就可以了;

    #include <bits/stdc++.h>
    #define inc(i,a,b) for(register int i=a;i<=b;i++)
    #define dec(i,a,b) for(register int i=a;i>=b;i--)
    using namespace std;
    int head[2000010],cnt;
    class littlestar{
    	public:
    		int to;
    		int nxt;
    		
    }star[2000010];
    void add(int u,int v){
    	star[++cnt].to=v;
    	star[cnt].nxt=head[u];
    	head[u]=cnt;
    }
    int n,m;
    template<class nT>
    inline void read(nT& x)
    {
    	char c;
    	while(c=getchar(),!isdigit(c));
    	x=c^48;
    	while(c=getchar(),isdigit(c)) x=x*10+c-48;
    }
    int a[2000010],val[2000010];
    int dep[2000010],f[1000010][30];
    void pre(int u,int fa)
    {
    	//printf("%d %d
    ",u,fa);
    	dep[u]=dep[fa]+1;
    	inc(i,0,20){
    		f[u][i+1]=f[f[u][i]][i];
    	}
    	for(register int i=head[u];i;i=star[i].nxt){
    		int v=star[i].to;
    		if(v==fa) continue;
    		f[v][0]=u;
    		pre(v,u);
    	}
    }
    int lca(int x,int y)
    {
    	if(dep[x]<dep[y]) swap(x,y);
    	dec(i,19,0){
    		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    		if(x==y) return x;
    	}
    	dec(i,19,0){
    		if(f[x][i]!=f[y][i]){
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	return f[x][0];
    }
    int rt[20000010];
    int num=0;	
    class node2{
    	public:
     		int l;
     		int r;
     		int w;
    }tree[20000010];
    void insert(int preroot,int &root,int l,int r,int goal){
    	tree[root=++num]=tree[preroot];
    	tree[root].w++;
    	if(l==r) return;
    	int mid=(l+r)>>1;
    	if(goal<=mid){
    		insert(tree[preroot].l,tree[root].l,l,mid,goal);
    	}
    	else{
    		insert(tree[preroot].r,tree[root].r,mid+1,r,goal);
    	}
    	tree[root].w=(tree[tree[root].l].w+tree[tree[root].r].w);
    }
    int query(int l,int r,int x,int y,int lc,int falc,int k){
    	if(l==r) return l;
    	int tmp=tree[tree[x].l].w+tree[tree[y].l].w-tree[tree[lc].l].w-tree[tree[falc].l].w;
    	int mid=(l+r)>>1;
    	if(k<=tmp){
    		return query(l,mid,tree[x].l,tree[y].l,tree[lc].l,tree[falc].l,k);
    	}
    	else{
    		return query(mid+1,r,tree[x].r,tree[y].r,tree[lc].r,tree[falc].r,k-tmp);
    	}
    }
    void dfs(int u)
    {
    	insert(rt[f[u][0]],rt[u],1,n,val[u]);
    	for(register int i=head[u];i;i=star[i].nxt){
    		int v=star[i].to;
    		if(v==f[u][0]) continue;
    		dfs(v);
    	}
    }
    int ago[2000010];
    signed main()
    {
    	//freopen("ha.in","r",stdin);
    	read(n); read(m);
    	inc(i,1,n) read(a[i]),val[i]=a[i];
    	inc(i,1,n-1){   
    		int u,v;
    		read(u); read(v);
    		add(u,v);
    		add(v,u);
    	}		
    	sort(a+1,a+1+n); 		
    	int lisan=unique(a+1,a+1+n)-a-1;
    	inc(i,1,n){
    		int tmp=val[i];
    		val[i]=lower_bound(a+1,a+1+lisan,val[i])-a;
    		ago[val[i]]=tmp;
    	}	
    	pre(1,0);
    	dfs(1);
    	int onlineans=0;
    	inc(i,1,m){
    		int u,v,k;
    		read(u);read(v);read(k);
    		u^=onlineans;
    		int LCA=lca(u,v);
    		int last=query(1,n,rt[u],rt[v],rt[LCA],rt[f[LCA][0]],k);
    		onlineans=ago[last];
    		printf("%d
    ",onlineans);
    	} 
    }
    
  • 相关阅读:
    【001】JS解析,反解析XML的一些问题
    [ Java面试题 ]并发篇
    [ Java面试题 ]WEB篇
    [ Java面试题 ]算法篇
    [ Java面试题 ]数据库篇
    [ Java面试题 ]泛型篇
    [ Java面试题 ]多线程篇
    [ Java面试题 ]持久层篇
    Java开发岗面试知识点解析
    [ SSH框架 ] Spring框架学习之二(Bean的管理和AOP思想)
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11675572.html
Copyright © 2011-2022 走看看