Description:

给定一颗n个点的树,有m个询问,求任意两点路径上点权第k小的点

Hint:

\(n,m<=1e5\)

Solution:

比较水

以每个点到根节点的数的前缀和建主席树

结合树上两点距离求法

每次的\(size=size[u]+size[v]-size[lca]-size[fa[lca]]\)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mxn=6e5+5;
  4. struct ed {
  5. int to,nxt;
  6. }t[mxn<<1];
  7. int n,m,s,tot,ans,cnt,hd[mxn],f[mxn][19],ls[mxn<<3],rs[mxn<<3],sum[mxn<<3],a[mxn],b[mxn],rt[mxn],dep[mxn];
  8. inline void add(int u,int v) {
  9. t[++cnt]=(ed){v,hd[u]},hd[u]=cnt;
  10. }
  11. void update(int las,int& p,int l,int r,int val)
  12. {
  13. if(!p) p=++tot;
  14. sum[p]=sum[las]+1;
  15. if(l==r) return ;
  16. int mid=(l+r)>>1;
  17. if(val<=mid) update(ls[las],ls[p],l,mid,val),rs[p]=rs[las];
  18. else update(rs[las],rs[p],mid+1,r,val),ls[p]=ls[las];
  19. }
  20. int query(int las1,int las2,int p1,int p2,int l,int r,int k)
  21. {
  22. if(l==r) return l;
  23. int tp=sum[ls[p1]]+sum[ls[p2]]-sum[ls[las1]]-sum[ls[las2]];
  24. int mid=(l+r)>>1;
  25. if(k<=tp) query(ls[las1],ls[las2],ls[p1],ls[p2],l,mid,k);
  26. else query(rs[las1],rs[las2],rs[p1],rs[p2],mid+1,r,k-tp);
  27. }
  28. void dfs(int u,int fa)
  29. {
  30. f[u][0]=fa; dep[u]=dep[fa]+1;
  31. update(rt[fa],rt[u],1,s,b[u]);
  32. for(int i=hd[u];i;i=t[i].nxt) {
  33. int v=t[i].to;
  34. if(v==fa) continue ;
  35. dfs(v,u);
  36. }
  37. }
  38. int LCA(int x,int y)
  39. {
  40. if(dep[x]<dep[y]) swap(x,y);
  41. for(int i=18;i>=0;--i)
  42. if(dep[f[x][i]]>=dep[y])
  43. x=f[x][i];
  44. if(x==y) return x;
  45. for(int i=18;i>=0;--i)
  46. if(f[x][i]!=f[y][i])
  47. x=f[x][i],y=f[y][i];
  48. return f[x][0];
  49. }
  50. void solve(int u,int v,int k)
  51. {
  52. u^=ans;
  53. int lca=LCA(u,v);
  54. ans=a[query(rt[lca],rt[f[lca][0]],rt[u],rt[v],1,s,k)];
  55. printf("%d\n",ans);
  56. }
  57. int main()
  58. {
  59. scanf("%d%d",&n,&m); int u,v,k;
  60. for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
  61. sort(a+1,a+n+1);
  62. s=unique(a+1,a+n+1)-a-1;
  63. for(int i=1;i<=n;++i) b[i]=lower_bound(a+1,a+s+1,b[i])-a;
  64. for(int i=1;i<n;++i) {
  65. scanf("%d%d",&u,&v);
  66. add(u,v); add(v,u);
  67. }
  68. dfs(1,0);
  69. for(int j=1;j<=18;++j)
  70. for(int i=1;i<=n;++i)
  71. f[i][j]=f[f[i][j-1]][j-1];
  72. for(int i=1;i<=m;++i) {
  73. scanf("%d%d%d",&u,&v,&k);
  74. solve(u,v,k);
  75. }
  76. return 0;
  77. }

[SP10628]Count on a tree的更多相关文章

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

  2. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

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

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

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

  4. 【BZOJ】【2588】COT(Count On a Tree)

    可持久化线段树 maya……树么……转化成序列……所以就写了个树链剖分……然后每个点保存的是从它到根的可持久化线段树. 然后就像序列一样查询……注意是多个左端点和多个右端点,处理方法类似BZOJ 19 ...

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

  6. spoj cot: Count on a tree 主席树

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

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

  8. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  9. SPOJ Count on a tree

    Count on a tree Time Limit:129MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Subm ...

随机推荐

  1. 【专栏学习】APM——异步编程模型(.NET不推荐)

    (1)learning hard C#学习笔记 异步1:<learning hard C#学习笔记>读书笔记(20)异步编程 (2)<C# 4.0 图解教程> 22.4 异步编 ...

  2. webpack学习笔记--配置resolve

    Resolve Webpack 在启动后会从配置的入口模块出发找出所有依赖的模块,Resolve 配置 Webpack 如何寻找模块所对应的文件. Webpack 内置 JavaScript 模块化语 ...

  3. std::string 是什么

    #include "stdafx.h" #include <iostream> #include <string> using std::cout; usi ...

  4. 数据库vertica 脚本方式的导入导出

    需要进入vsql下的: 导入: copy emp from '/tmp/emp.csv' DELIMITER ',' ESCAPE AS '\' ENCLOSED BY '"' DIRECT ...

  5. .NET Core在安装(VS2015)与部署

    .NET Core开发环境搭建 使用VS2015开发.NET Core项目,环境的搭建可以参考官网,大致安装步骤如下: 1.首先你得装个vs2015 并且保证已经升级至 update3及以上,下载链接 ...

  6. canvas给图片加水印

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 解决 jQuery 实现父窗口的问题 如window.parent.document.getElementById().innerHTML

    因为先前遇到的问题,所以我考虑采用 IFRAME 来隔离不同的脚本,从而实现我需要的效果. 在框架中,我用 JavaScript 获取 JSON 数据,组织成 HTML 代码,最后将其填充至上层文档的 ...

  8. jQuery Validate自定义错误信息,自定义方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 设计模式之单例模式及应用demo

    单例模式是创建型模式之一. 单例模式顾名思义是单例的,也就是只有一个实例化对象,这都来源于它的私有化构造函数. 单例模式特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3. ...

  10. Spring(二)IOC底层实现原理

    IOC原理 将对象创建交给Spring去管理. 实现IOC的两种方式 IOC配置文件的方式 IOC注解的方式 IOC底层实现原理 底层实现使用的技术 1.1 xml配置文件 1.2 dom4j解析xm ...