题目描述

设T 为一棵有根树,我们做如下的定义:
? 设a和b为T 中的两个不同节点。如果a是b的祖先,那么称“a比b不知道
高明到哪里去了”。
? 设a 和 b 为 T 中的两个不同节点。如果 a 与 b 在树上的距离不超过某个给定
常数x,那么称“a 与b 谈笑风生”。
给定一棵n个节点的有根树T,节点的编号为1 到 n,根节点为1号节点。你需
要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a;b;c)满足:
1. a、b和 c为 T 中三个不同的点,且 a为p 号节点;
2. a和b 都比 c不知道高明到哪里去了;
3. a和b 谈笑风生。这里谈笑风生中的常数为给定的 k。

输入

第一行含有两个正整数n和q,分别代表有根树的点数与询问的个数。
接下来n - 1行,每行描述一条树上的边。每行含有两个整数u和v,代表在节点u和v之间有一条边。
接下来q行,每行描述一个操作。第i行含有两个整数,分别表示第i个询问的p和k。
1<=P<=N
1<=K<=N
N<=300000
Q<=300000
 

输出

输出 q 行,每行对应一个询问,代表询问的答案。

样例输入

5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3

样例输出

3
1
3

提示

Hint:边要加双向

  题目大意:给定一个n个节点的有根树,q次询问,每次询问两个数p,k,问满足1、a,b都是c的祖先。2、a编号为p。3、a,b距离<=k。的三元组(a,b,c)有多少个。

  因为a,b都是c的祖先,所以它们其中一个一定是另一个的祖先。a的位置确定了,那就讨论b的位置:当b是a祖先时,直接将a子树大小乘上k和a的深度中小的那个就好了;当a是b祖先时,a子树中与a深度差<=k的点都可以是b,统计这些点的子树和就是答案,也就相当于将每个点的子树大小作为这个点的点权(要将自己刨去)求点权和。如果没有层数限制直接将dfs序架在线段树上区间求和就好了。但有了限制就要用主席树按深度建树,每个深度建一棵线段树,维护这一深度所有点的信息,查询时依旧是查a点子树区间,但因为深度>dep[a]+k的点在主席树中还没有维护信息所以并不影响。

  1. #include<set>
  2. #include<map>
  3. #include<queue>
  4. #include<cmath>
  5. #include<stack>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<cstring>
  9. #include<iostream>
  10. #include<algorithm>
  11. typedef long long ll;
  12. using namespace std;
  13. ll ans;
  14. int mx;
  15. int n,m;
  16. int p,k;
  17. int x,y;
  18. int num;
  19. int tot;
  20. int cnt;
  21. int s[300010];
  22. int t[300010];
  23. int d[300010];
  24. int to[600010];
  25. int ls[6000010];
  26. int rs[6000010];
  27. ll sum[6000010];
  28. int head[300010];
  29. int next[600010];
  30. int size[300010];
  31. int root[300010];
  32. struct node
  33. {
  34. int dep;
  35. int id;
  36. }a[300010];
  37. bool cmp(node a,node b)
  38. {
  39. return a.dep<b.dep;
  40. }
  41. void add(int x,int y)
  42. {
  43. tot++;
  44. next[tot]=head[x];
  45. head[x]=tot;
  46. to[tot]=y;
  47. }
  48. void dfs(int x,int fa)
  49. {
  50. num++;
  51. s[x]=num;
  52. a[x].dep=a[fa].dep+1;
  53. d[x]=d[fa]+1;
  54. size[x]=1;
  55. for(int i=head[x];i;i=next[i])
  56. {
  57. if(to[i]!=fa)
  58. {
  59. dfs(to[i],x);
  60. size[x]+=size[to[i]];
  61. }
  62. }
  63. t[x]=num;
  64. }
  65. int updata(int pre,int l,int r,int k,int v)
  66. {
  67. int rt=++cnt;
  68. if(l==r)
  69. {
  70. sum[rt]=sum[pre]+v;
  71. return rt;
  72. }
  73. ls[rt]=ls[pre];
  74. rs[rt]=rs[pre];
  75. sum[rt]=sum[pre]+v;
  76. int mid=(l+r)>>1;
  77. if(k<=mid)
  78. {
  79. ls[rt]=updata(ls[pre],l,mid,k,v);
  80. }
  81. else
  82. {
  83. rs[rt]=updata(rs[pre],mid+1,r,k,v);
  84. }
  85. return rt;
  86. }
  87. ll query(int x,int y,int l,int r,int L,int R)
  88. {
  89. if(L<=l&&r<=R)
  90. {
  91. return sum[y]-sum[x];
  92. }
  93. int mid=(l+r)>>1;
  94. if(L>mid)
  95. {
  96. return query(rs[x],rs[y],mid+1,r,L,R);
  97. }
  98. else if(R<=mid)
  99. {
  100. return query(ls[x],ls[y],l,mid,L,R);
  101. }
  102. return query(ls[x],ls[y],l,mid,L,R)+query(rs[x],rs[y],mid+1,r,L,R);
  103. }
  104. int main()
  105. {
  106. scanf("%d%d",&n,&m);
  107. for(int i=1;i<n;i++)
  108. {
  109. scanf("%d%d",&x,&y);
  110. add(x,y);
  111. add(y,x);
  112. a[i].id=i;
  113. }
  114. a[n].id=n;
  115. dfs(1,0);
  116. sort(a+1,a+1+n,cmp);
  117. for(int i=1;i<=n;i++)
  118. {
  119. mx=max(mx,d[i]);
  120. if(a[i].dep>a[i-1].dep)
  121. {
  122. root[a[i].dep]=root[a[i-1].dep];
  123. }
  124. root[a[i].dep]=updata(root[a[i].dep],1,n,s[a[i].id],size[a[i].id]-1);
  125. }
  126. for(int i=1;i<=m;i++)
  127. {
  128. scanf("%d%d",&p,&k);
  129. ans=0;
  130. ans+=1ll*min(k,d[p]-1)*(size[p]-1);
  131. ans+=query(root[d[p]],root[min(d[p]+k,mx)],1,n,s[p],t[p]);
  132. printf("%lld\n",ans);
  133. }
  134. }

BZOJ3653谈笑风生——可持久化线段树+dfs序的更多相关文章

  1. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  2. 【CF768G】The Winds of Winter 可持久化线段树 DFS序

    题目大意 给定一棵\(n\)个点的树,对于树上每个结点,将它删去,然后可以将得到的森林中任意一个点与其父亲断开并连接到另一颗树上,对每一个点求出森林中所有树\(size\)最大值的最小值. \(n\l ...

  3. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  4. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  5. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  6. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  7. bzoj 3653: 谈笑风生 可持久化线段树

    题目大意 在一棵单位边权的有根树上支持询问: 给定a,k求满足下列条件的有序三元对的个数. a,b,c互不相同 a,b均为c的祖先 a,b树上距离<=k 题解 solution 1 首先我们知道 ...

  8. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  9. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

随机推荐

  1. 【Codeforces 1105E】Helping Hiasat

    Codeforces 1105 E 题意:给你m个事件,每个事件可能是以下两种之一: \(1\),代表此时可以更改用户名 \(2\) \(s\),代表\(s\)来查看是否用户名与其名字相符 一共有\( ...

  2. Selenium:WebDriver简介及元素定位

    参考内容:官方API文档,下载链接:http://download.csdn.net/detail/kwgkwg001/4004500 虫师:<selenium2自动化测试实战-基于python ...

  3. GZIP压缩提高网络传输效率

    [spring]通过GZIP压缩提高网络传输效率(可以实现任何资源的gzip压缩.包括AJAX) gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将 ...

  4. C++11 并发指南二(std::thread 详解)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

  5. 解密:Python风靡全宇宙,首要原因竟是它?

    就让我们从近年来大数据的兴起说起,为你娓娓道来Python火爆的真正原因. 郁闷的大数据程序员 随着大数据的崛起,大多数行业发现自己进入了一种恐慌状态:他们花费了大量的时间和金钱来建立他们的大数据渠道 ...

  6. 4.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—第四章小结

    本章相关重要命令总结在Table 6. 命令 描述 示例 mkdir <name> 创建某目录 $ mkdir foo pwd 显示当前所在目录 $ pwd cd <dir> ...

  7. AngularJs的ng-include的使用与实现

    想在angularjs动态加载一个内容,我们可以使用ng-include来实现. 今天Insus.NET就在ASP.NET MVC环境中,举个例子来演示它的功能. 你可以在一个视图动态加载任一其它视图 ...

  8. flask_admin 笔记七 扩展功能

    高级功能 1,开启CSRF保护 要将CSRF保护添加到由ModelView实例生成的表单中,请通过指定form_base_class参数在ModelView子类中使用SecureForm类: from ...

  9. SpringMvc返回Json调试

    spring-web-5.0.6.RELEASE.jar!/org/springframework/web/method/support/HandlerMethodReturnValueHandler ...

  10. mongo java 踩坑记

    为什么会有这么多坑 1.  Java会把 id:String = "合法ObjectId"  好心好意的 转为  _id:ObjectId 类型. 2. 为了避免第1点, 我定义了 ...