题目:

Description

设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。

Input

输入文件的第一行含有两个正整数n和q,分别代表有根树的点数与询问的个数。接下来n – 1行,每行描述一条树上的边。每行含有两个整数u和v,代表在节点u和v之间有一条边。
接下来q行,每行描述一个操作。第i行含有两个整数,分别表示第i个询问的p和k。

Output

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

Sample Input

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

Sample Output

3
1
3

HINT

1<=P<=N
1<=K<=N
N<=300000
Q<=300000

题解:

线段树以深度为关键字维护size的和

x,y的答案  = size[x] * min(deep[x], y) + dfs序在l[x] + 1到r[x]之间且深度在deep[x] + 1到deep[x] + k之间的size和

挺有收获的一道题···第一次发现主席树每个节点的表示区间可以与其在第几棵树无关。

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<ctime>
  6. #include<cctype>
  7. #include<cstring>
  8. #include<string>
  9. #include<algorithm>
  10. using namespace std;
  11. int read()
  12. {
  13. int x=;char ch=getchar();
  14. while(ch<''||ch>'')ch=getchar();
  15. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  16. return x;
  17. }
  18. const int N=3e5+;
  19. struct node
  20. {
  21. int l,r;
  22. long long size;
  23. }tree[N<<];
  24. int root[N],totr=;
  25. int first[N],next[N*],go[N*],tot=;
  26. int cnt=,que[N],in[N],out[N],deep[N],maxdeep=,size[N];
  27. int n,q;
  28. inline void comb(int a,int b)
  29. {
  30. next[++tot]=first[a],first[a]=tot,go[tot]=b;
  31. next[++tot]=first[b],first[b]=tot,go[tot]=a;
  32. }
  33. inline void dfs(int u,int fa)
  34. {
  35. in[u]=++cnt;
  36. size[u]=;
  37. que[cnt]=u;
  38. for(int e=first[u];e;e=next[e])
  39. {
  40. int v=go[e];
  41. if(v==fa) continue;
  42. deep[v]=deep[u]+;
  43. maxdeep=max(maxdeep,deep[v]);
  44. dfs(v,u);
  45. size[u]+=size[v];
  46. }
  47. out[u]=cnt;
  48. }
  49. inline void build(int &now,int l,int r,int deep,int size)
  50. {
  51. tree[++totr]=tree[now],now=totr;
  52. tree[now].size+=size;
  53. if(l==r) return;
  54. int mid=(l+r)/;
  55. if(deep<=mid) build(tree[now].l,l,mid,deep,size);
  56. if(deep>mid) build(tree[now].r,mid+,r,deep,size);
  57. }
  58. //------------------------------------
  59. inline void Insert(const int &x, int &y, const int &l, const int &r, const int &pos, const int &v){
  60. tree[y = ++totr] = tree[x];
  61. tree[y].size += v;
  62. if(l == r) return;
  63. int mid = l + r >> ;
  64. if(pos <= mid) Insert(tree[x].l, tree[y].l, l, mid, pos, v);
  65. else Insert(tree[x].r, tree[y].r, mid + , r, pos, v);
  66. }
  67. //---------------------------------------
  68. inline long long query(int k,int l,int r,int x,int y)
  69. {
  70. if(x <= l && r <= y)
  71. return tree[k].size;
  72. int mid=(l+r)/;
  73. long long temp=;
  74. if(x<=mid) temp+=query(tree[k].l,l,mid,x,y);
  75. if(y>mid) temp+=query(tree[k].r,mid+,r,x,y);
  76. return temp;
  77. }
  78. int main()
  79. {
  80. //freopen("a.in","r",stdin);
  81. n=read();
  82. q=read();
  83. int a,b;
  84. for(int i=;i<n;i++)
  85. {
  86. a=read();
  87. b=read();
  88. comb(a,b);
  89. }
  90. dfs(,);
  91. for(int i=;i<=cnt;i++)
  92. {
  93. root[i]=root[i-];
  94. build(root[i],,maxdeep,deep[que[i]],size[que[i]]-);
  95. }
  96. //for(int i = 1; i <= n; i++) Insert(root[i - 1], root[i], 0, maxdeep, deep[que[i]],size[que[i]]-1);
  97. while(q--)
  98. {
  99. scanf("%d%d",&a,&b);
  100. long long ans=;
  101. ans+=(long long) (size[a]-)*(long long)min(deep[a],b);
  102. ans+=query(root[out[a]],,maxdeep,min(deep[a]+,maxdeep),min(deep[a]+b,maxdeep));
  103. ans-=query(root[in[a]-],,maxdeep,min(deep[a]+,maxdeep),min(deep[a]+b,maxdeep));
  104. cout<<ans<<endl;
  105. }
  106. return ;
  107. }

刷题总结——谈笑风生(主席树+dfs序的应用)的更多相关文章

  1. 51 nod 1681 公共祖先 (主席树+dfs序)

    1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...

  2. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

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

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

  4. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

    题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...

  5. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  6. BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...

  7. BZOJ - 2809 dispatching 主席树+dfs序

    在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的 ...

  8. BZOJ3772 精神污染 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3772 题意概括 给出一个树,共n个节点. 有m条互不相同的树上路径. 现在让你随机选择2条路径,问 ...

  9. BZOJ5338[TJOI2018]xor——主席树+dfs序

    题目描述 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操作,操作如下: 1  x y    查询节点x的子树中与y异或结果的最大值 2 x y z     ...

随机推荐

  1. SQL 时间日期函数

    1.获取当前日期GetDate getdate()函数以datetime数据类型的格式返回当前SQLServer服务器所在计算机的日期和时间.其语法格式为getdate().返回值舍入到最近的秒小数部 ...

  2. SQL增删查改语句

    一.增:有4种方法 1.使用insert插入单行数据: 语法:insert [into] <表名> [列名] values <列值> insert into sheet1 va ...

  3. 10个优秀的移动Web应用开发框架

    在最近几年里,移动互联网高速发展.市场潜力巨大.继计算机.互联网之后,移动互联网正掀起第三次信息技术革命的浪潮,新技术.新应用不断涌现.今天这篇文章向大家推荐10大优秀的移动Web开发框架,帮助开发者 ...

  4. 数据库_8_SQL基本操作——数据操作

    SQL基本操作——数据操作 一.新增数据(两种方案) 方案1: 给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致,凡是非数值数据,都需要使用引号(建议是 ...

  5. Java的jdbc调用SQL Server存储过程Bug201906131120

    如果要查询结果,第一行使用set nocount on;可能可以解决问题.

  6. node mocha mochawesome报安装不成功

    1.进行cnpm安装: npm install cnpm -g --registry=https://registry.npm.taobao.org 2.查看cnpm版本 cnpm -v 3.安装mo ...

  7. POI写入word doc 03 模板的实例

    在使用POI写word doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过HWPFDocument来写的,而HWPFDocument是要依附于一个doc文件的.所以通 ...

  8. shell脚本,锁机制

    [root@localhost wyb]# cat suijizhi.sh #!/bin/bash a=`|grep -v grep |wc -l` echo "$a" [ $a ...

  9. Promise中的next 另一个用法

    const chainAsync = fns => { let curr = 0 ; const next = (...args) => fns[curr++](next,...args) ...

  10. APIO2019&&THUSC2019游记

    APIO2019懵十三记: day0: 早上和ljx从沈阳出发,下午一点到的首师大附. 由于工作人员中午十二点就散了,我们就先去试机了. 下午三点接到狗牌和T恤,晚上买麦当劳回如意吃. 晚上还有场模拟 ...