• BZOJ2588: Spoj 10628. Count on a tree


    题解: 树上主席树转移 建权值线段树即可(

    #include <bits/stdc++.h>
    const int MAXN=1e5+10;
    using namespace std;
    typedef struct node{
    	int l,r,sum;
    }node;
    node d[MAXN*21];int rt[MAXN],cnt,f[MAXN][21],a[MAXN];
    vector<int>vec[MAXN];
    int n,m;
    void update(int &x,int y,int l,int r,int t){
    	x=++cnt;d[x]=d[y];d[x].sum++;
    	if(l==r)return ;
    	int mid=(l+r)>>1;
    	if(t<=mid)update(d[x].l,d[y].l,l,mid,t);
    	else update(d[x].r,d[y].r,mid+1,r,t);
    }
    int querty(int x,int y,int x1,int y1,int l,int r,int k){
    	if(l==r)return l;
    	int mid=(l+r)>>1;
    	int t1=d[d[x1].l].sum+d[d[y1].l].sum-d[d[x].l].sum-d[d[y].l].sum;
    	if(t1>=k)return querty(d[x].l,d[y].l,d[x1].l,d[y1].l,l,mid,k);
    	else return querty(d[x].r,d[y].r,d[x1].r,d[y1].r,mid+1,r,k-t1);
    }
    int dep[MAXN];
    void dfs(int v,int pre,int deep){
    	f[v][0]=pre;dep[v]=deep+1;
    	update(rt[v],rt[pre],1,n,a[v]);
    	for(int i=0;i<vec[v].size();i++){
    		if(vec[v][i]!=pre)dfs(vec[v][i],v,deep+1);
    	}
    }
    void dfs1(int v){
    	for(int i=1;i<=20;i++)f[v][i]=f[f[v][i-1]][i-1];
    	for(int i=0;i<vec[v].size();i++)if(vec[v][i]!=f[v][0])dfs1(vec[v][i]);
    }
    int Lca(int u,int v){
    	if(dep[u]<dep[v])swap(u,v);
    	int tmp=dep[u]-dep[v];
    	for(int i=0;i<=20;i++)if((tmp&(1<<i)))u=f[u][i];
    	if(u==v)return u;
    	for(int i=20;i>=0;i--){
    		if(f[u][i]!=f[v][i]){
    			u=f[u][i];v=f[v][i];
    		}
    	}
    	return f[u][0];
    }
    vector<int>v1;
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]),v1.push_back(a[i]);
    	sort(v1.begin(),v1.end());
    	int sz=unique(v1.begin(),v1.end())-v1.begin();
    	for(int i=1;i<=n;i++)a[i]=lower_bound(v1.begin(),v1.begin()+sz,a[i])-v1.begin()+1;
    	int u,v,res=0,k;
    	for(int i=1;i<n;i++)scanf("%d%d",&u,&v),vec[u].push_back(v),vec[v].push_back(u);
    	dfs(1,0,0);dfs1(1);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&u,&v,&k);
    		u^=res;int lca=Lca(u,v);
    		res=v1[querty(rt[lca],rt[f[lca][0]],rt[u],rt[v],1,n,k)-1];
    		printf("%d
    ",res);
    	}
    	return 0;
    }
    

    2588: Spoj 10628. Count on a tree

    Time Limit: 12 Sec  Memory Limit: 128 MB
    Submit: 8749  Solved: 2224
    [Submit][Status][Discuss]

    Description

    给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

    Input

    第一行两个整数N,M。
    第二行有N个整数,其中第i个整数表示点i的权值。
    后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
    最后M行每行两个整数(u,v,k),表示一组询问。

    Output

    M行,表示每个询问的答案。最后一个询问不输出换行符

    Sample Input

    8 5
    105 2 9 3 8 5 7 7
    1 2
    1 3
    1 4
    3 5
    3 6
    3 7
    4 8
    2 5 1
    0 5 2
    10 5 3
    11 5 4
    110 8 2

    Sample Output

    2
    8
    9
    105
    7

    HINT



    HINT:
    N,M<=100000
    暴力自重。。。
  • 相关阅读:
    【OpenJudge 2.5-1792】这绝壁是一道玄学题!【DFS】
    【BZOJ1034】省队选手不务正业打泡泡堂(我也不知道是啥算法)
    文件操作的常用方法和使用
    数据类型所有方法和使用整理之------字典
    数据类型所有方法和使用整理之------列表
    用类的内置方法实现类型检查
    类的内置方法及描述符
    用python实现MRO算法
    RHEL6.5 DHCP服务器搭建
    Python之禅 吾心笃定
  • 原文地址:https://www.cnblogs.com/wang9897/p/9461172.html
Copyright © 2020-2023  润新知