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
  1. /*
  2. 树上第K大
  3. 对于每一个节点,维护一棵权值线段树,记录它到根节点的状态,询问的时候,类似于区间第K大,这条链上的
  4. 总数就是sum[a]+sum[b]-sum[lca]-sum[fa[lca]]
  5. */
  6. #include<cstdio>
  7. #include<iostream>
  8. #include<algorithm>
  9. #define N 200010
  10. using namespace std;
  11. int a[N],b[N],val[N],n,m,len;
  12. int head[N],fa[N][],dep[N],root[N],lc[N*],rc[N*],sum[N*],cnt;
  13. struct node{int v,pre;}e[N*];
  14. void add(int i,int u,int v){
  15. e[i].v=v;
  16. e[i].pre=head[u];
  17. head[u]=i;
  18. }
  19. void pushup(int now){
  20. sum[now]=sum[lc[now]]+sum[rc[now]];
  21. }
  22. void change(int last,int &now,int x,int l,int r){
  23. now=++cnt;
  24. if(l==r){
  25. sum[now]=sum[last]+;
  26. return;
  27. }
  28. int mid=l+r>>;
  29. if(x<=mid) change(lc[last],lc[now],x,l,mid),rc[now]=rc[last];
  30. else change(rc[last],rc[now],x,mid+,r),lc[now]=lc[last];
  31. pushup(now);
  32. }
  33. void dfs(int x,int f,int c){
  34. dep[x]=c;fa[x][]=f;change(root[f],root[x],a[x],,len);
  35. for(int i=head[x];i;i=e[i].pre){
  36. if(e[i].v==f) continue;
  37. dfs(e[i].v,x,c+);
  38. }
  39. }
  40. void get_fa(){
  41. for(int j=;j<=;j++)
  42. for(int i=;i<=n;i++)
  43. fa[i][j]=fa[fa[i][j-]][j-];
  44. }
  45. int get_same(int u,int t){
  46. for(int i=;i<=;i++)
  47. if(t&(<<i))
  48. u=fa[u][i];
  49. return u;
  50. }
  51. int LCA(int u,int v){
  52. if(dep[u]<dep[v]) swap(u,v);
  53. u=get_same(u,dep[u]-dep[v]);
  54. if(u==v) return u;
  55. for(int i=;i>=;i--)
  56. if(fa[u][i]!=fa[v][i])
  57. u=fa[u][i],v=fa[v][i];
  58. return fa[u][];
  59. }
  60. int query(int a,int b,int A,int B,int k,int l,int r){
  61. int x=sum[lc[a]]+sum[lc[b]]-sum[lc[A]]-sum[lc[B]];
  62. if(l==r) return l;
  63. int mid=l+r>>;
  64. if(k<=x) return query(lc[a],lc[b],lc[A],lc[B],k,l,mid);
  65. else return query(rc[a],rc[b],rc[A],rc[B],k-x,mid+,r);
  66. }
  67. int main(){
  68. scanf("%d%d",&n,&m);
  69. for(int i=;i<=n;i++){
  70. scanf("%d",&a[i]);
  71. b[i]=a[i];
  72. }
  73. sort(b+,b+n+);
  74. len=unique(b+,b+n+)-b-;
  75. for(int i=;i<=n;i++){
  76. int t=lower_bound(b+,b+len+,a[i])-b;
  77. val[t]=a[i];a[i]=t;
  78. }
  79. for(int i=;i<n;i++){
  80. int u,v;scanf("%d%d",&u,&v);
  81. add(i*-,u,v);add(i*,v,u);
  82. }
  83. dfs(,,);get_fa();
  84. int ans=;
  85. for(int i=;i<=m;i++){
  86. int u,v,k;scanf("%d%d%d",&u,&v,&k);u^=ans;
  87. int anc=LCA(u,v);
  88. ans=val[query(root[u],root[v],root[anc],root[fa[anc][]],k,,len)];
  89. printf("%d",ans);
  90. if(i!=m) printf("\n");
  91. }
  92. return ;
  93. }

Count on a tree(bzoj 2588)的更多相关文章

  1. 【BZOJ2588】Count On a Tree(主席树)

    [BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...

  2. bzoj 2588 Spoj 10628. Count on a tree(主席树)

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

  3. hdu 4670 Cube number on a tree(点分治)

    Cube number on a tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/ ...

  4. 04-树6 Complete Binary Search Tree(30 分)

    title: 04-树6 Complete Binary Search Tree(30 分) date: 2017-11-12 14:20:46 tags: - 完全二叉树 - 二叉搜索树 categ ...

  5. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  6. 1127 ZigZagging on a Tree (30 分)

    1127 ZigZagging on a Tree (30 分) Suppose that all the keys in a binary tree are distinct positive in ...

  7. 【PAT】1043 Is It a Binary Search Tree(25 分)

    1043 Is It a Binary Search Tree(25 分) A Binary Search Tree (BST) is recursively defined as a binary ...

  8. 1110 Complete Binary Tree (25 分)

    1110 Complete Binary Tree (25 分) Given a tree, you are supposed to tell if it is a complete binary t ...

  9. 【POJ1741】Tree(点分治)

    [POJ1741]Tree(点分治) 题面 Vjudge 题目大意: 求树中距离小于\(K\)的点对的数量 题解 完全不觉得点分治了.. 简直\(GG\),更别说动态点分治了... 于是来复习一下. ...

随机推荐

  1. leetcode_1048. Longest String Chain_[DP,动态规划,记忆化搜索]

    1048. Longest String Chain https://leetcode.com/problems/longest-string-chain/ Let's say word1 is a ...

  2. shelll脚本,根据软链接,找到真实路径

    [root@localhost tmp]# ls -l total lrwxrwxrwx root root Sep : abc -> /etc/passwd lrwxrwxrwx root r ...

  3. shell脚本,计算从0+2+4+6+....100的结果是多少?

    [root@localhost wyb]# cat evenjia.sh #!/bin/bash #从0++++...100的结果 i= ` do sum=$(($sum+i)) i=$(($i+)) ...

  4. rhel7.3smb安装配置

    rhel7.3smb安装配置 1.安装 yum -y install samba samba-client cifs-utils 2.配置开机自启动,覆盖原配置文件 systemctl enable ...

  5. 自写小函数处理 javascript 0.3*0.2 浮点类型相乘问题

    const reg = /^([-+]?)([0-9]+)\.([0-9]*)$/; // 判断是不是浮点数 const isFloat = function(number){ return reg. ...

  6. How To:Linux下如何通过命令检查网卡是否插上网线

    主要工具为ethtool来检查,主要关注的字段为"Link detected",注意如下的输出,其中em4实际物理上并未插上网线,而em1是插上网线的: # ethtool em4 ...

  7. POJ 2255 Tree Recovery——二叉树的前序遍历、后序遍历、中序遍历规则(递归)

    1.前序遍历的规则:(根左右) (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 对于图中二叉树,前序遍历结果:ABDECF 2.中序遍历的规则:(左根右) (1)中序遍历左子树 (2)访 ...

  8. 哪些 Python 库让你相见恨晚?

    知乎用户,A European Swallow. 苇叶.Aran He.jerry等人赞同 补充三个有助于自动化日常工作的: sh:sh 1.08 — sh v1.08 documentation可以 ...

  9. 手动搭建redis集群(3台)

    安装redis 1.搜索源中的redis包 apt-cache pkgnames | grep redis 2.安装redis-server apt-get install redis-server ...

  10. Python解释器镜像源修改

    目录 Windows Mac 这篇文章将解除你使用python的pip install xxx受到的网速限制,如果只是下载较小的第三方库,可以尝试pip --default-timeout=100 i ...