BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树

题意:

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

分析:

每个结点开线段树,保存到根这段路径上的权值,然后类似树上差分在主席树上求第k小

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. #define N 100050
  6. int head[N],to[N<<1],nxt[N<<1];
  7. int top[N],fa[N],dep[N],son[N],siz[N],tot,cnt;
  8. int n,m,root[N],t[N*50],ls[N*50],rs[N*50],a[N],see;
  9. struct A{
  10. int num,id,v;
  11. }d[N];
  12. bool cmp1(const A &x,const A &y){return x.num<y.num;}
  13. bool cmp2(const A &x,const A &y){return x.id<y.id;}
  14. inline void add(int u,int v){
  15. to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
  16. }
  17. void rd(int &x){
  18. int f=1;x=0;char s=getchar();
  19. while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
  20. while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}x*=f;
  21. }
  22. void dfs1(int x){
  23. siz[x]=1;
  24. for(int i=head[x];i;i=nxt[i])if(to[i]!=fa[x]){
  25. fa[to[i]]=x;dep[to[i]]=dep[x]+1;
  26. dfs1(to[i]);
  27. siz[x]+=siz[to[i]];
  28. if(siz[to[i]]>siz[son[x]])son[x]=to[i];
  29. }
  30. }
  31. void dfs2(int x,int t){
  32. top[x]=t;
  33. if(son[x])dfs2(son[x],t);
  34. for(int i=head[x];i;i=nxt[i])if(to[i]!=fa[x]&&to[i]!=son[x])dfs2(to[i],to[i]);
  35. }
  36. int LCA(int x,int y){
  37. while(top[x]!=top[y]){
  38. if(dep[top[x]]>dep[top[y]])swap(x,y);
  39. y=fa[top[y]];
  40. }
  41. return dep[x]<dep[y]?x:y;
  42. }
  43. void insert(int x,int &y,int l,int r,int val){
  44. y=++tot;
  45. if(l==r){t[y]=t[x]+1;return ;}
  46. int mid=l+r>>1;
  47. if(val<=mid) rs[y]=rs[x],insert(ls[x],ls[y],l,mid,val);
  48. else ls[y]=ls[x],insert(rs[x],rs[y],mid+1,r,val);
  49. t[y]=t[ls[y]]+t[rs[y]];
  50. }
  51. int query(int x,int y,int lca,int f,int l,int r,int k){
  52. if(l==r)return a[l];
  53. int mid=l+r>>1,sizls=t[ls[x]]+t[ls[y]]-t[ls[lca]]-t[ls[f]];
  54. if(k<=sizls) return query(ls[x],ls[y],ls[lca],ls[f],l,mid,k);
  55. else return query(rs[x],rs[y],rs[lca],rs[f],mid+1,r,k-sizls);
  56. }
  57. void build(int x){
  58. for(int i=head[x];i;i=nxt[i]){
  59. if(to[i]!=fa[x]){
  60. insert(root[x],root[to[i]],1,n,d[to[i]].v);
  61. build(to[i]);
  62. }
  63. }
  64. }
  65. int main(){
  66. rd(n);rd(m);
  67. int i,x,y,k,j;
  68. for(i=1;i<=n;i++) rd(d[i].num),d[i].id=i;
  69. sort(d+1,d+n+1,cmp1);
  70. d[0].num=-1000000;
  71. for(j=0,i=1;i<=n;i++){if(d[i].num!=d[i-1].num)j++;d[i].v=j;a[j]=d[i].num;}
  72. sort(d+1,d+n+1,cmp2);
  73. for(i=1;i<n;i++) {
  74. rd(x);rd(y);
  75. add(x,y);add(y,x);
  76. }
  77. dep[1]=1;fa[1]=0;
  78. dfs1(1);dfs2(1,1);
  79. int ans=0;
  80. //for(i=1;i<=n;i++) insert(root[fa[a[i]]],root[a[i]],minn,maxn,v[a[i]]);
  81. insert(root[0],root[1],1,n,d[1].v);
  82. build(1);
  83. for(i=1;i<=m;i++) {
  84. scanf("%d%d%d",&x,&y,&k);x^=ans;
  85. int lca=LCA(x,y);
  86. ans=query(root[x],root[y],root[lca],root[fa[lca]],1,n,k);
  87. if(i<m)
  88. printf("%d\n",ans);
  89. else printf("%d",ans);
  90. }
  91. }

BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树的更多相关文章

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

  2. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  3. SPOJ 10628 Count on a tree (lca+主席树)

    题意:给定一棵有n个结点的树,每一个点有一个权值.共同拥有m个询问.对于每一个询问(u,v,k),回答结点u至v之间第k小的点的权值. 思路:主席树+lca.首先指定一个根结点dfs一次并在此过程中建 ...

  4. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

  5. [SCOI2015]情报传递[树剖+主席树]

    [SCOI2015]情报传递 题意大概就是 使得在 \(i\) 时刻加入一个情报员帮您传情报 然后询问 \(x,y,c\) 指 \(x\)到\(y\)多少个人有风险-(大于c)的都有风险-每天风险值+ ...

  6. [HNOI2015]开店(树剖+主席树+标记永久化)

    听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...

  7. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  8. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  9. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

随机推荐

  1. rotate image(旋转数组)

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  2. javascript学习(二)javascript常见问题总结

    在js使用过程中,经常会碰到一些问题,本人利用闲暇时间整理了一些常见问题的解决方法,贴出来和大家分享,有需要的朋友可以参考下 1.JS中方法和变量都是区分大小写的  2.单引号.双引号在JS中没有特殊 ...

  3. 【JDK1.8】JUC——AbstractQueuedSynchronizer

    一.前言 在上一篇中,我们对LockSupport进行了阅读,因为它是实现我们今天要分析的AbstractQueuedSynchronizer(简称AQS)的基础,重新用一下最开始的图: 可以看到,在 ...

  4. Django之AppConfig源码学习

    class AppConfig(object) 这个基类描述了一个Django应用以及它的配置信息. 属性: name:django应用的完整python路径,eg.'django.contrib.a ...

  5. docker的安装和技巧

    工作了有一段时间,开发环境中需要docker环境,但是docker一直不算很熟,之前一直是利用yum安装,但是yum安装真的很费劲,所以总结了一些经验给大家: 1,利用yum直接安装 官网是直接给了y ...

  6. (译)WebRTC实战: STUN, TURN, Signaling

    http://xiaol.me/2014/08/24/webrtc-stun-turn-signaling/ 原文:WebRTC in the real world: STUN, TURN and s ...

  7. Roundcube Webmail File Disclosure Vulnerability(CVE-2017-16651)

    Preface Software: https://roundcube.net/ Versions: 1.1.0 - 1.1.9, 1.2.0 - 1.2.6, 1.3.0 - 1.3.2 CVE: ...

  8. Scala编程入门---函数式编程

    高阶函数 Scala中,由于函数时一等公民,因此可以直接将某个函数传入其他函数,作为参数.这个功能是极其强大的,也是Java这种面向对象的编程语言所不具备的. 接收其他函数作为函数参数的函数,也被称作 ...

  9. nltk download失败

    之前在台式机win10的系统,python 2.7,用的pycharm执行nltk download(),很顺利.然而到了我的笔记本只是换个一个win8的系统,Python的配置都是一样的,但是这时候 ...

  10. lintcode 在O(1)时间复杂度删除链表节点

    题目要求 给定一个单链表中的一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点. 样例 Linked list is 1->2->3->4, and giv ...