【刷题】BZOJ 2588 Spoj 10628. Count on a tree
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
N,M<=100000
Solution
一个典型的树上差分,然后维护第\(k\)大。。主席树嘛
我们主席树的每个版本是从它的父亲处继承过来的,那么它维护的就是这个节点到根节点路径上的信息
那么我们的差分就是
\]
查询就在这个差分后的树上找就行了
#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
#define Mid ((l+r)>>1)
#define lson l,Mid
#define rson Mid+1,r
const int MAXN=100000+10;
int n,m,A[MAXN],Jie[MAXN][20],dep[MAXN],e,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],ans;
std::vector<int> V;
std::map<int,int> M;
struct ChairMan_Tree{
    int cnt,lc[MAXN<<5],rc[MAXN<<5],sum[MAXN<<5],root[MAXN];
	inline void init()
	{
		cnt=0;
		memset(lc,0,sizeof(lc));
		memset(rc,0,sizeof(rc));
		memset(sum,0,sizeof(sum));
	}
    inline void Build(int &rt,int l,int r)
    {
        rt=++cnt;
        sum[rt]=0;
        if(l==r)return ;
        Build(lc[rt],lson);
        Build(rc[rt],rson);
    }
    inline void Insert(int &rt,int l,int r,int last,int pos)
    {
        rt=++cnt;
        sum[rt]=sum[last]+1;
        lc[rt]=lc[last];
        rc[rt]=rc[last];
        if(l==r)return ;
        else
        {
			if(pos<=Mid)Insert(lc[rt],lson,lc[last],pos);
			else Insert(rc[rt],rson,rc[last],pos);
        }
    }
	inline int Query(int left,int right,int gfa,int grand,int l,int r,int k)
	{
		if(l==r)return l;
		else
		{
			int t=sum[lc[left]]+sum[lc[right]]-sum[lc[gfa]]-sum[lc[grand]];
			if(k<=t)return Query(lc[left],lc[right],lc[gfa],lc[grand],lson,k);
			else return Query(rc[left],rc[right],rc[gfa],rc[grand],rson,k-t);
		}
	}
};
ChairMan_Tree T;
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
    to[++e]=y;
    nex[e]=beg[x];
    beg[x]=e;
}
inline void discre()
{
    sort(V.begin(),V.end());
    V.erase(unique(V.begin(),V.end()),V.end());
    for(register int i=1;i<=n;++i)
    {
        int pre=A[i];
        A[i]=lower_bound(V.begin(),V.end(),A[i])-V.begin()+1;
        M[A[i]]=pre;
    }
}
inline void dfs(int x,int f,int d)
{
	T.Insert(T.root[x],1,n,T.root[f],A[x]);
	dep[x]=d;
	Jie[x][0]=f;
	for(register int i=beg[x];i;i=nex[i])
		if(to[i]==f)continue;
		else dfs(to[i],x,d+1);
}
inline void init()
{
	for(register int j=1;j<20;++j)
		for(register int i=1;i<=n;++i)Jie[i][j]=Jie[Jie[i][j-1]][j-1];
}
inline int LCA(int u,int v)
{
	if(dep[u]<dep[v])std::swap(u,v);
	if(dep[u]>dep[v])
		for(register int i=19;i>=0;--i)
			if(dep[Jie[u][i]]>=dep[v])u=Jie[u][i];
	if(u==v)return u;
	for(register int i=19;i>=0;--i)
		if(Jie[u][i]!=Jie[v][i])u=Jie[u][i],v=Jie[v][i];
	return Jie[u][0];
}
int main()
{
    read(n);read(m);
    for(register int i=1;i<=n;++i)
    {
        read(A[i]);
        V.push_back(A[i]);
    }
    discre();
    for(register int i=1;i<n;++i)
    {
        int u,v;
        read(u);read(v);
        insert(u,v);
        insert(v,u);
    }
	T.init();
	T.Build(T.root[0],1,n);
	dfs(1,0,1);
	init();
    while(m--)
    {
        int u,v,k,lca;
        read(u);read(v);read(k);
        u^=ans;
		lca=LCA(u,v);
        ans=M[T.Query(T.root[u],T.root[v],T.root[Jie[lca][0]],T.root[lca],1,n,k)];
		write(ans,'\n');
    }
    return 0;
}
												
											【刷题】BZOJ 2588 Spoj 10628. Count on a tree的更多相关文章
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
		
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
 - BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
		
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
 - Bzoj 2588: Spoj 10628. Count on a tree  主席树,离散化,可持久,倍增LCA
		
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
 - BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
		
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
 - Bzoj  2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)
		
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...
 - bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
		
Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 7669 Solved: 1894[Submi ...
 - 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree
		
题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...
 - ●BZOJ 2588 Spoj 10628. Count on a tree
		
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...
 - BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
		
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
 
随机推荐
- Post请求和Get请求;@RequestBody和@RequestParam
			
1.@RequestBody用于Post请求,接收json数据,例如:@RequestBody User user 例如:@RequestBody Map map .不要用于Get请求. 2.@Req ...
 - vue.js和vue-router和vuex快速上手知识
			
vue.js和vue-router和vuex快速上手知识 一直以来,认为vue相比react而言,学习成本会更低,会更简单,但最近真正接触后,发现vue的各方面都有做一些客户化的优化,有一些亮点,但也 ...
 - 使用CDN后配置nginx自定义日志获取访问用户的真实IP
			
问题描述: 新上线了一个项目,架构如下(简单画的理解就好): 问题是:负载前面加上CDN后负载这里无法获取客户的真实访问IP,只能过去到CDN的IP地址: 问题解决: 修改nginx日 ...
 - react-native初体验(2) — 认识路由
			
如果学习止步于 hello world, 那么人生也太没意思了.这次要做一个看起来真实的应用.多添加几个页面,让他们可以交互,动起来. react-native 官方推荐使用 react-naviga ...
 - Docker Manager for Kubernetes
			
一.Kubernetes介绍 Kubernets是Google开源的容器集群系统,是基于Docker构建一个容器的调度服务,提供资源调度,均衡容灾,服务注册,动态伸缩等功能套件: Kubernets提 ...
 - vim文本编辑工具(全)
			
VIM文本编辑工具 编辑模式 i 在当前字符前插入I 在光标所在的行首插入a 在当前字符后插入A 在光标所在行尾插入o 在当前行的下一行插入新的一行O 在当前行的上一行插入新的一行 s ...
 - 如何判断Map中的key或value是什么类型
			
在上班写工具类时,遇到了一个问题,将xml文件的节点都放入map容器中时,map的value也是一个map,导致取map的value时,需要判断这个value的数据类型,用到了一下说的这些知识: 对于 ...
 - linux 安装配置kafka脚本
			
安装脚本 #!/bin/bash # auto install kafka echo "========= Start to install kafka ==============&quo ...
 - 简单安装与使用虚拟环境virtualenv
			
安装虚拟环境的命令如下: sudo pip install virtualenv sudo pip install virtualenvwrapper 创建虚拟环境的命令如下: mkvirtualen ...
 - LeetCode 461. Hamming Distance (C++)
			
题目: The Hamming distance between two integers is the number of positions at which the corresponding ...