Description

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

Solution

类似区间第K大,主席树套个LCA就行了

对于树上两个节点x和y,设他们的LCA为a,且a的父节点为b

那么x到y的这段区间就为\((T[x]-T[b])+(T[x]-T[b])+T[a]\) (节点a会重复减去)

\(T[i]\)表示以\(i\)节点建立的线段树

Code

#include <cstdio>
#include <algorithm>
#include <cmath>
#define N 100010
using namespace std; struct info{int to,nex;}e[N*2];
int n,m,A[N],rank[N],T[N],ls[N*20],rs[N*20],sum[N*20],tot,cnt,preAns;
int _log,fa[N],head[N],f[N][20],dep[N]; inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
} void Link(int u,int v){
e[++tot].nex=head[u];
e[tot].to=v;
head[u]=tot;
} void update(int last,int p,int l,int r,int &rt){
rt=++tot;
ls[rt]=ls[last],rs[rt]=rs[last],sum[rt]=sum[last]+1;
if(l==r) return;
int m=(l+r)>>1;
if(p<=m) update(ls[last],p,l,m,ls[rt]);
else update(rs[last],p,m+1,r,rs[rt]);
} void dfs(int u,int fa){
update(T[fa],A[u],1,cnt,T[u]);
for(int i=1;i<=_log;++i)
f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa) continue;
dep[v]=dep[u]+1;
f[v][0]=u;
dfs(v,u);
}
} int LCA(int u,int v){
if(dep[u]>dep[v]) swap(u,v);
int d=dep[v]-dep[u]; for(int i=0;i<=_log;++i)
if(d&(1<<i)) v=f[v][i];
if(u==v) return v; for(int i=_log;i>=0;--i)
if(f[u][i]!=f[v][i]){
u=f[u][i];
v=f[v][i];
}
return f[u][0];
} int query(int l,int r,int x,int y,int a,int b,int k){
if(l==r) return l;
int m=(l+r)>>1,d=sum[ls[x]]-sum[ls[b]]+sum[ls[y]]-sum[ls[a]];
if(d>=k) return query(l,m,ls[x],ls[y],ls[a],ls[b],k);
else return query(m+1,r,rs[x],rs[y],rs[a],rs[b],k-d);
} int main(){
n=read(),m=read();
_log=log(n)/log(2);
for(int i=1;i<=n;++i) A[i]=rank[i]=read();
sort(rank+1,rank+n+1);
cnt=unique(rank+1,rank+n+1)-(rank+1);
for(int i=1;i<=n;++i) A[i]=lower_bound(rank+1,rank+cnt+1,A[i])-rank;
for(int i=1;i<n;++i){
int u=read(),v=read();
Link(u,v);Link(v,u);
}
tot=0;
dfs(1,0);
while(m--){
int u=read()^preAns,v=read(),k=read();
int lca=LCA(u,v);
printf("%d",preAns=rank[query(1,cnt,T[u],T[v],T[lca],T[f[lca][0]],k)]);
if(m>0) printf("\n");
}
return 0;
}

[Bzoj2588]Count on a tree(主席树+LCA)的更多相关文章

  1. [bzoj2588][count on a tree] (主席树+lca)

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

  2. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  3. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  4. SPOJ Count on a tree(主席树+LCA)

    一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to  ...

  5. BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

    分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...

  6. BZOJ2588:Count on a tree(主席树)

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

  7. spoj COT - Count on a tree(主席树 +lca,树上第K大)

    您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...

  8. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  9. 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 ...

  10. 【bzoj2588】Count on a tree 主席树

    这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...

随机推荐

  1. pygame 使用

    模块概况 display image event key mouse font 类概况 Rect: 返回的矩阵区域(图片) Surface: 可以看做是一个贴图, 它就是来显示的 display(与显 ...

  2. 如何从MYSQL官方YUM仓库安装MYSQL5.x 原理一样只要获取对的仓库依赖安装对的仓库依赖就ok了,我就是用这种安装的5.7

    如何从MYSQL官方YUM仓库安装MYSQL5.6 2013年10月,MySQL开发团队正式宣布支持Yum仓库,这就意味着我们现在可以从这个Yum库中获得最新和最优版的MySQL安装包.本文将在一台全 ...

  3. webpack 安装后提示CLI

    webpack 4X 后需要安装webpack-cli 请注意需要安装在同一目录 npm install --save-dev webpack -g 输入以上命令后: webpack -v 提示: T ...

  4. Google常用拓展插件

    1.web前端助手(FEhelper)提供一些实用的前端小工具,功能十分贴心 2.bookMarks Manager 一个书签管理工具 3.Clear Cache 清除浏览器的缓存,有很多供选择的条目 ...

  5. Unicode字符集

    Unicode字符集的出现是为了弥补ASCII码只能表示128个字符的限制.在实际应用中,如若我们想显示汉字或日文等等,显然使用ASCII是不可能的.Unicode占用了两个字节,即16位,能表示的字 ...

  6. Liunx开发(Extjs4.1+desktop+SSH2超强视频教程实践)(1)

    下周一出差宁波了,周六日就折腾点视频: 跟着视频教程开发,不过开发环境换linux,上月找工作,某个吉祥物是松鼠的公司要求用linux开发,没用过的,连面试机会都不给,极其高冷:好吧,咱就试试,用li ...

  7. postman传递参数的问题

    postman是一款通过post或者get发送请求测试代码的工具 如果是类的话,就选择JSON格式,如果是一个字段的方法,就直接写入方法值就好了比如 public PageResult<Info ...

  8. Excel如何显示隐藏列?

    我们在工作中遇到excel表格数据太多比较负责,同时字段太多需要隐藏一些不重要的字段方便阅读和分析其他数据那么我们如何取消隐藏数据呢?隐藏列比较简单选中点隐藏就可以了,取消隐藏需要一些小的技巧才能灵活 ...

  9. Object comparison - (BOOL)isEqual:(id)other

    https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Obje ...

  10. 生成.m文件的python代码中出现的错误

    错误代码 import tempfile import subprocess import shlex import os import numpy as np import scipy.io scr ...