zoukankan      html  css  js  c++  java
  • BZOJ 2588 Spoj 10628. Count on a tree

    题解:主席树,上一层为父亲节点对应的主席树

    查询就用 u+v-lca-fa[lca]即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=200009;
    
    int n,m;
    int lastans;
    int v[maxn];
    int cntedge;
    int head[maxn];
    int to[maxn<<1],nex[maxn<<1];
    void Addedge(int x,int y){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	head[x]=cntedge;
    }
    
    int b[maxn],nn;
    int root[maxn];
    int PTsiz;
    struct PresidentTree{
    	int l,r,d,ls,rs;
    }tree[maxn*20];
    void BuildTree(int &now,int l,int r){
    	now=++PTsiz;
    	tree[now].l=l;tree[now].r=r;tree[now].d=0;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	BuildTree(tree[now].ls,l,mid);
    	BuildTree(tree[now].rs,mid+1,r);
    }
    void Updatapoint(int &now,int pre,int p){
    	now=++PTsiz;
    	tree[now]=tree[pre];
    	tree[now].d++;
    	if(tree[now].l==tree[now].r)return;
    	int mid=(tree[now].l+tree[now].r)>>1;
    	if(p<=mid)Updatapoint(tree[now].ls,tree[pre].ls,p);
    	else Updatapoint(tree[now].rs,tree[pre].rs,p);
    }
    int Querykth(int x,int y,int z,int w,int k){
    	if(tree[x].l==tree[x].r)return b[tree[x].l];
    	int d=tree[tree[x].ls].d+tree[tree[y].ls].d-tree[tree[z].ls].d-tree[tree[w].ls].d;
    	if(k<=d)return Querykth(tree[x].ls,tree[y].ls,tree[z].ls,tree[w].ls,k);
    	else return Querykth(tree[x].rs,tree[y].rs,tree[z].rs,tree[w].rs,k-d);
    }
    
    int f[maxn][20];
    int depth[maxn];
    void Dfs(int now,int fa){
    	f[now][0]=fa;
    	depth[now]=depth[fa]+1;
    	int p=lower_bound(b+1,b+1+nn,v[now])-b;
    	Updatapoint(root[now],root[fa],p);
    	for(int i=head[now];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		Dfs(to[i],now);
    	}
    }
    
    void LCAinit(){
    	for(int j=1;j<=19;++j){
    		for(int i=1;i<=n;++i){
    			f[i][j]=f[f[i][j-1]][j-1];
    		}
    	}
    }
    int Querylca(int u,int v){
    	if(depth[u]<depth[v])swap(u,v);
    	for(int j=19;j>=0;--j){
    		if(depth[f[u][j]]>=depth[v])u=f[u][j];
    	}
    	if(u==v)return u;
    	for(int j=19;j>=0;--j){
    		if(f[u][j]!=f[v][j]){
    			u=f[u][j];v=f[v][j];
    		}
    	}
    	return f[u][0];
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&v[i]);b[i]=v[i];
    	}
    	sort(b+1,b+1+n);
    	nn=unique(b+1,b+1+n)-b-1;
    	for(int i=1;i<=n-1;++i){
    		int x,y;scanf("%d%d",&x,&y);
    		Addedge(x,y);Addedge(y,x);
    	}
    	
    	BuildTree(root[0],1,n);
    	Dfs(1,0);
    	LCAinit();
    	
    	while(m--){
    		int u,v,k;
    		scanf("%d%d%d",&u,&v,&k);
    		u^=lastans;
    		int lca=Querylca(u,v);
    		printf("%d",lastans=Querykth(root[u],root[v],root[lca],root[f[lca][0]],k));
    		if(m!=0)printf("
    ");
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    k8s中文网
    python range用法
    python 日志滚动 分文件
    python 语法
    flask 中文编码解码
    python的杨辉三角
    mysql8.0.4以后修改密码方式变更
    flask学习视频
    oralce的lag和lead函数
    JNI 各类数据类型处理
  • 原文地址:https://www.cnblogs.com/zzyer/p/8456419.html
Copyright © 2011-2022 走看看