zoukankan      html  css  js  c++  java
  • BZOJ 2588

    http://www.lydsy.com/JudgeOnline/problem.php?id=2588

    在树上建主席树

    每个节点按它的father建一颗新树

    对于路径(u,v)等价于(1,u)+(1,v)-(1,lca(u,v))-(1,fa[lca(u,v)])

    root[u],root[v],root[lca(u,v)],root[fa[lca(u,v)]]

    然后在这4棵主席树上差分,取出k小值

    #include<cstdio>
    #include<algorithm>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    using namespace std;
    const int N=100011,NlogN=2000011;
    struct Tree{
    	int ls,rs,sum;
    	#define ls(now) (tr[now].ls)
    	#define rs(now) (tr[now].rs)
    	#define sum(now) (tr[now].sum)
    }tr[NlogN];
    int rt[N];
    int n,m,ans,a[N],b[N];
    int x,y,p,k,cnt;
    inline void disc_init(){
    	sort(b+1,b+b[0]+1);
    	b[0]=unique(b+1,b+b[0]+1)-b-1;
    	FOR(i,1,n)a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b;
    }
    struct edge{
    	int to;edge *nxt;
    	#define VIS(now) for(edge *it=las[now];it;it=it->nxt)
    	#define to(it) (it->to)
    }e[N<<1],*las[N],*tot=e;
    int top[N],fa[N],dep[N],sz[N];
    inline void add(int x,int y){
    	*++tot=(edge){y,las[x]},las[x]=tot;
    }
    inline void dfs1(int now){
    	int to;sz[now]=1;
    	VIS(now)
    		if(!dep[to(it)]){
    			dep[to(it)]=dep[now]+1;fa[to(it)]=now;
    			dfs1(to(it));sz[now]+=sz[to(it)];
    		}
    }
    inline void build(int cpy,int &now,int l,int r,int pos){
    	tr[now=++cnt]=tr[cpy];++sum(now);
    	if(l==r)return;int mid=(l+r)>>1;
    	pos<=mid?build(ls(cpy),ls(now),l,mid,pos):build(rs(cpy),rs(now),mid+1,r,pos);
    }
    inline int query(int a,int b,int c,int d,int l,int r,int k){
    	if(l==r)return l;
    	int data=sum(ls(a))+sum(ls(b))-sum(ls(c))-sum(ls(d));
    	int mid=(l+r)>>1;
    	return k<=data?query(ls(a),ls(b),ls(c),ls(d),l,mid,k):query(rs(a),rs(b),rs(c),rs(d),mid+1,r,k-data);
    }
    inline void dfs2(int now,int chain){
    	top[now]=chain;build(rt[fa[now]],rt[now],1,b[0],a[now]);
    	register int i=0;
    	VIS(now)if(fa[now]!=(to(it))&&sz[to(it)]>sz[i])i=to(it);
    	if(!i)return;dfs2(i,chain);
    	VIS(now)if(fa[now]!=(to(it))&&i!=to(it))dfs2(to(it),to(it));
    }
    inline int lca(int x,int y){
    	for(;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 main(){
    	scanf("%d%d",&n,&m);
    	FOR(i,1,n)scanf("%d",a+i),b[++b[0]]=a[i];
    	disc_init();
    	FOR(i,2,n){
    		scanf("%d%d",&x,&y);
    		add(x,y);add(y,x);
    	}
    	dep[1]=1;dfs1(1);dfs2(1,1);
    	while(m--){
    		scanf("%d%d%d",&x,&y,&k);
    		x^=ans;p=lca(x,y);
    		ans=b[query(rt[x],rt[y],rt[p],rt[fa[p]],1,b[0],k)];
    		printf("%d",ans);
    		if(m)putchar('
    ');
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    安装Python,输入pip命令报错———pip Fatal error in launcher: Unable to create process using
    转摘python3.4 + pycharm 环境安装 + pycharm使用
    canvas学习总结三:绘制路径-线段
    Canvas学习系列二:Canvas的坐标系统
    Canvas学习系列一:初识canvas
    正确理解——容错、高可用和灾备
    nginx学习(三)——nginx高可用方案nginx+keepalived
    nginx学习(二)——模块指令介绍
    win10下VMware15安装centos7
    centos7 安装jdk8
  • 原文地址:https://www.cnblogs.com/Stump/p/7967091.html
Copyright © 2011-2022 走看看