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

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cmath>
  4. #define N 100010
  5. using namespace std;
  6. struct info{int to,nex;}e[N*2];
  7. int n,m,A[N],rank[N],T[N],ls[N*20],rs[N*20],sum[N*20],tot,cnt,preAns;
  8. int _log,fa[N],head[N],f[N][20],dep[N];
  9. inline int read(){
  10. int x=0,f=1;char ch=getchar();
  11. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  12. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  13. return x*f;
  14. }
  15. void Link(int u,int v){
  16. e[++tot].nex=head[u];
  17. e[tot].to=v;
  18. head[u]=tot;
  19. }
  20. void update(int last,int p,int l,int r,int &rt){
  21. rt=++tot;
  22. ls[rt]=ls[last],rs[rt]=rs[last],sum[rt]=sum[last]+1;
  23. if(l==r) return;
  24. int m=(l+r)>>1;
  25. if(p<=m) update(ls[last],p,l,m,ls[rt]);
  26. else update(rs[last],p,m+1,r,rs[rt]);
  27. }
  28. void dfs(int u,int fa){
  29. update(T[fa],A[u],1,cnt,T[u]);
  30. for(int i=1;i<=_log;++i)
  31. f[u][i]=f[f[u][i-1]][i-1];
  32. for(int i=head[u];i;i=e[i].nex){
  33. int v=e[i].to;
  34. if(v==fa) continue;
  35. dep[v]=dep[u]+1;
  36. f[v][0]=u;
  37. dfs(v,u);
  38. }
  39. }
  40. int LCA(int u,int v){
  41. if(dep[u]>dep[v]) swap(u,v);
  42. int d=dep[v]-dep[u];
  43. for(int i=0;i<=_log;++i)
  44. if(d&(1<<i)) v=f[v][i];
  45. if(u==v) return v;
  46. for(int i=_log;i>=0;--i)
  47. if(f[u][i]!=f[v][i]){
  48. u=f[u][i];
  49. v=f[v][i];
  50. }
  51. return f[u][0];
  52. }
  53. int query(int l,int r,int x,int y,int a,int b,int k){
  54. if(l==r) return l;
  55. int m=(l+r)>>1,d=sum[ls[x]]-sum[ls[b]]+sum[ls[y]]-sum[ls[a]];
  56. if(d>=k) return query(l,m,ls[x],ls[y],ls[a],ls[b],k);
  57. else return query(m+1,r,rs[x],rs[y],rs[a],rs[b],k-d);
  58. }
  59. int main(){
  60. n=read(),m=read();
  61. _log=log(n)/log(2);
  62. for(int i=1;i<=n;++i) A[i]=rank[i]=read();
  63. sort(rank+1,rank+n+1);
  64. cnt=unique(rank+1,rank+n+1)-(rank+1);
  65. for(int i=1;i<=n;++i) A[i]=lower_bound(rank+1,rank+cnt+1,A[i])-rank;
  66. for(int i=1;i<n;++i){
  67. int u=read(),v=read();
  68. Link(u,v);Link(v,u);
  69. }
  70. tot=0;
  71. dfs(1,0);
  72. while(m--){
  73. int u=read()^preAns,v=read(),k=read();
  74. int lca=LCA(u,v);
  75. printf("%d",preAns=rank[query(1,cnt,T[u],T[v],T[lca],T[f[lca][0]],k)]);
  76. if(m>0) printf("\n");
  77. }
  78. return 0;
  79. }

[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. Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22499   Accepted: 7679 De ...

  2. using System.Web.Script.Serialization

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...

  3. Day1上

    上午发挥强差人意.心态不好,编译器一直报错,心里比较慌. t1 每一个P枚举底数 .可二分 T2 暴力30  打标60 x^3-y^3=(x-y)*(x^2+xy+y^2). x-y==1.  ! p ...

  4. 大数据kafka视频教程 学习记录【B站尚硅谷 】

    视频地址: https://www.bilibili.com/video/av35354301/?p=1           2019/03/06 21:59 消息队列的内部实现: Kafka基础: ...

  5. javascript之 JavaScript 工具库

    javascript之 JavaScript 工具库jQuery 目录: 一.查找标签和事件绑定以及操作标签的对比 二.DOM对象和jquery的转换 三.$(document).ready( )  ...

  6. 未整理js

    函数+对象=方法 方法是动作 有参数的函数=实例 使用new关键字和函数来创建一个实例 var p =new Point(1,1)//平面几何的点 表示遍历的语句样子: for(var i =0; i ...

  7. Apache Solr-6.0.1 (OpenLogic CentOS 7.2)

    Apache Solr-6.0.1 (OpenLogic CentOS 7.2) 平台: CentOS 类型: 虚拟机镜像 软件包: java1.8 solr6.0.1 application ser ...

  8. 巧用netsh命令实现端口转发(端口映射)不求人

    好处:即时生效,随意修改删除,不影响其他ip映射 记事本保存为bat格式批量添加后,并查看映射: netsh interface portproxy add v4tov4 listenport=701 ...

  9. MVC下c#对接微信公众平台开发者模式

    在ashx文件中进行HttpContext的处理: using System; using System.Collections.Generic; using System.Linq; using S ...

  10. cms-详细页面-3

    1.设置上一条.下一条数据 2.使用昌言插件 3.点击链接帖子的访问数加一 1.在mapper中设置分页: <?xml version="1.0" encoding=&quo ...