2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 5217  Solved: 1233
[Submit][Status][Discuss]

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

HINT:
N,M<=100000

每个节点建一棵主席树,维护树上前缀和
每次u和v之间的就是ls(u)+ls(v)-ls(lca(u,v))-ls(fa[lca(u,v)])
很多人用了dfs序的编号,没有必要
 
注意:
1.数组空间!!!!
2.lca用树剖的话,建树时dfs的顺序也要先重链!!!!!
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. const int N=1e5+,INF=1e9+;
  8. int read(){
  9. char c=getchar();int x=,f=;
  10. while(c<''||c>''){if(c=='-')f=-; c=getchar();}
  11. while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
  12. return x*f;
  13. }
  14. int n,Q,u,v,k,last,mp[N],m,w[N];
  15. struct ques{
  16. int u,v,k;
  17. }q[N];
  18. int Bin(int v){
  19. int l=,r=m;
  20. while(l<=r){
  21. int mid=(l+r)>>;
  22. if(mp[mid]==v) return mid;
  23. else if(v<mp[mid]) r=mid-;
  24. else l=mid+;
  25. }
  26. return -;
  27. }
  28. struct edge{
  29. int v,ne;
  30. }e[N<<];
  31. int h[N],cnt;
  32. inline void ins(int u,int v){
  33. cnt++;
  34. e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
  35. cnt++;
  36. e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
  37. }
  38. int size[N],fa[N],deep[N],mx[N],top[N],tid[N],tot;
  39. void dfs(int u){
  40. size[u]=;
  41. for(int i=h[u];i;i=e[i].ne){
  42. int v=e[i].v;
  43. if(v==fa[u]) continue;
  44. fa[v]=u;deep[v]=deep[u]+;
  45. dfs(v);
  46. size[u]+=size[v];
  47. if(size[mx[u]]<size[v]) mx[u]=v;
  48. }
  49. }
  50. void dfs(int u,int anc){
  51. if(!u) return;
  52. tid[u]=++tot;
  53. top[u]=anc;
  54. dfs(mx[u],anc);
  55. for(int i=h[u];i;i=e[i].ne){
  56. int v=e[i].v;
  57. if(v!=fa[u]&&v!=mx[u]) dfs(v,v);
  58. }
  59. }
  60. int lca(int x,int y){
  61. while(top[x]!=top[y]){
  62. if(deep[top[x]]<deep[top[y]]) swap(x,y);
  63. x=fa[top[x]];
  64. }
  65. if(tid[x]>tid[y]) swap(x,y);
  66. return x;
  67. }
  68.  
  69. struct node{
  70. int l,r,size;
  71. }t[N*];
  72. int sz,root[N];
  73. void insert(int &x,int l,int r,int num){
  74. t[++sz]=t[x];x=sz;
  75. t[x].size++;
  76. if(l==r) return;
  77. int mid=(l+r)>>;
  78. if(num<=mid) insert(t[x].l,l,mid,num);
  79. else insert(t[x].r,mid+,r,num);
  80. }
  81. void build(int u){
  82. root[u]=root[fa[u]];
  83. insert(root[u],,m,Bin(w[u]));
  84. if(mx[u]) build(mx[u]);
  85. for(int i=h[u];i;i=e[i].ne)
  86. if(e[i].v!=fa[u]&&e[i].v!=mx[u]) build(e[i].v);
  87. }
  88. inline int ls(int x){return t[t[x].l].size;}
  89. int query(int u,int v,int k){
  90. int p=lca(u,v),q=fa[p];
  91. u=root[u];v=root[v];p=root[p];q=root[q];
  92. int l=,r=m;
  93. while(l!=r){
  94. int mid=(l+r)>>,_=ls(u)+ls(v)-ls(p)-ls(q);
  95. if(k<=_) r=mid,u=t[u].l,v=t[v].l,p=t[p].l,q=t[q].l;
  96. else l=mid+,u=t[u].r,v=t[v].r,p=t[p].r,q=t[q].r,k-=_;
  97. }
  98. return l;
  99. }
  100. int main(){
  101. n=read();Q=read();
  102. for(int i=;i<=n;i++) mp[i]=w[i]=read();
  103. for(int i=;i<=n-;i++) u=read(),v=read(),ins(u,v);
  104. dfs();dfs(,);
  105. for(int i=;i<=Q;i++) q[i].u=read(),q[i].v=read(),q[i].k=read();
  106. sort(mp+,mp++n);
  107. m=;
  108. for(int i=;i<=n;i++) if(mp[i]!=mp[i-]) mp[++m]=mp[i];
  109.  
  110. build();
  111. for(int i=;i<=Q;i++){
  112. u=last^q[i].u;v=q[i].v;k=q[i].k;
  113. last=mp[query(u,v,k)];
  114. printf("%d",last);
  115. if(i!=Q) putchar('\n');
  116. }
  117. }
 
 

BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]的更多相关文章

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

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

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

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

  3. bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】

    算是板子,把值离散化,每个点到跟上做主席树,然后查询的时候主席树上用u+v-lca-fa[lca]的值二分 #include<iostream> #include<cstdio> ...

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

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

  6. 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个节点的树,每个点 ...

  7. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

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

  9. 主席树 || 可持久化线段树 || 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) ...

随机推荐

  1. HTTP的长连接和短连接

        本文总结&分享网络编程中涉及的长连接.短连接概念.     关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持长连接(HTT ...

  2. Beginners Guide To Web Development

    Web Development Front End Development Back End Development

  3. .NET MVC Razor模板预编译(二)

    在前面一片文章:<.NET MVC4 Razor视图预编译(一)> 里面我采用的是PrecompiledMvcViewEngineContrib组件进行预编译视图的虚拟地址注册,但是这个组 ...

  4. CRL2.3(ORM开发框架)源码github发布

    简介 CRL是一个面向对象的轻便型ORM业务框架 此框架追求的是使用简单,方便,因此设计为: 不需要代码生成器生成对象类,按标准方式写即可 依托lambda,实现语法解析转换为等效的SQL查询,完全以 ...

  5. 打造android偷懒神器———ListView的万能适配器

    如果你去做任何一个项目,我相信你都会跟我有一样的经历,最最普遍的就是列表显示ListView,当然,写N个自定义的适配器也是情理之中.虽说程序员本身就是搬砖,做这些枯燥无味的重复的事情也是理所当然,但 ...

  6. CSS3属性 box-shadow 向框添加一个或多个阴影

    CSS3属性 利用box-shadow制作网页页眉背景 box-shadow 浏览器支持 IE9+.Firefox 4.Chrome.Opera 以及 Safari 5.1.1 支持 box-shad ...

  7. Ionic2系列——使用DeepLinker实现指定页面URL

    Ionic2使用了近似原生App的页面导航方式,并不支持Angular2的路由.这种方式在开发本地App的时候比较方便,但如果要用来开发纯Web页面就有点问题了,这种情况下Angular2的route ...

  8. [C1] 优化 C1FlexGrid 单元格边框

    一  优化理由 如下图所示,如果按照 C1FlexGrid 自带的单元格边框设置,即对每个单元格的 CellStyle 的 BorderThickness 进行设置,会得到如下图的效果: 其中,明显可 ...

  9. Linux下安装Hadoop完全分布式(Ubuntu12.10)

    Hadoop的安装非常简单,可以在官网上下载到最近的几个版本,最好使用稳定版.本例在3台机器集群安装.hadoop版本如下: 工具/原料 hadoop-0.20.2.tar.gz Ubuntu12.1 ...

  10. 最小生成树计数 bzoj 1016

    最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...