3653: 谈笑风生

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 628  Solved: 245
[Submit][Status][Discuss]

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

Source

Solution

答案显然是$(size[x]-1)*min(deep[x],K)+\sum_{dis(x,y)<=K,y\epsilon x}^{y}(size[y]-1)$

考虑求后面那些东西,可以利用可持久化线段树来做

用deep作为下标,维护size。

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. int read()
  8. {
  9. int x=,f=; char ch=getchar();
  10. while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
  11. while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
  12. return x*f;
  13. }
  14. #define MAXN 300010
  15. #define LL long long
  16. int N,Q;
  17. struct EdgeNode{int next,to;}edge[MAXN<<];
  18. int head[MAXN],cnt=;
  19. void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
  20. void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);}
  21. int deep[MAXN],size[MAXN],pl[MAXN],pr[MAXN],pre[MAXN],dfn,maxd;
  22. void DFS(int now,int last)
  23. {
  24. pl[now]=++dfn; pre[dfn]=now; size[now]=;
  25. maxd=max(maxd,deep[now]);
  26. for (int i=head[now]; i; i=edge[i].next)
  27. if (edge[i].to!=last)
  28. {
  29. deep[edge[i].to]=deep[now]+;
  30. DFS(edge[i].to,now);
  31. size[now]+=size[edge[i].to];
  32. }
  33. pr[now]=dfn;
  34. }
  35. struct SegmentTreeNode{int ls,rs; LL sum;}tree[MAXN*];
  36. int root[MAXN],sz;
  37. void Update(int &now,int last,int l,int r,int pos,int val)
  38. {
  39. now=++sz;
  40. tree[now].sum=tree[last].sum+val;
  41. if (l==r) return;
  42. int mid=(l+r)>>;
  43. tree[now].ls=tree[last].ls,tree[now].rs=tree[last].rs;
  44. if (pos<=mid) Update(tree[now].ls,tree[last].ls,l,mid,pos,val);
  45. else Update(tree[now].rs,tree[last].rs,mid+,r,pos,val);
  46. }
  47. LL Query(int now,int l,int r,int L,int R)
  48. {
  49. if (!now) return 0LL;
  50. if (L==l && R==r) return tree[now].sum;
  51. int mid=(l+r)>>;
  52. if (R<=mid) return Query(tree[now].ls,l,mid,L,R);
  53. else if (L>mid) return Query(tree[now].rs,mid+,r,L,R);
  54. else return Query(tree[now].ls,l,mid,L,mid)+Query(tree[now].rs,mid+,r,mid+,R);
  55. }
  56. int main()
  57. {
  58. N=read(),Q=read();
  59. for (int x,y,i=; i<=N-; i++) x=read(),y=read(),InsertEdge(x,y);
  60. DFS(,);
  61. // for (int i=1; i<=N; i++)
  62. // printf("%d [%d , %d] %d %d\n",pre[i],pl[pre[i]],pr[pre[i]],size[pre[i]],deep[pre[i]]);
  63. for (int i=; i<=N; i++) Update(root[i],root[i-],,maxd,deep[pre[i]],size[pre[i]]-);
  64. for (int i=; i<=Q; i++)
  65. {
  66. int p=read(),K=read();
  67. LL ans=0LL;
  68. ans=(LL)(size[p]-)*min(deep[p],K)+Query(root[pr[p]],,maxd,deep[p]+,deep[p]+K)-Query(root[pl[p]-],,maxd,deep[p]+,deep[p]+K);
  69. printf("%lld\n",ans);
  70. }
  71. return ;
  72. }

被Char哥-拍死了

【BZOJ-3653】谈笑风生 DFS序 + 可持久化线段树的更多相关文章

  1. BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)

    首先嘛,还是太弱了,想了好久QAQ 然后,这道题么,明显就是求sigma(size[x]) (x是y的儿子且层树小于k) 然后就可以发现:把前n个节点按深度建可持久化线段树,就能用前缀和维护了 其实不 ...

  2. 【bzoj4771】七彩树 树链的并+STL-set+DFS序+可持久化线段树

    题目描述 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义 ...

  3. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  4. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

  5. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  6. hdu5692【dfs序】【线段树】

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

  7. bzoj 4504: K个串 可持久化线段树+堆

    题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...

  8. bzoj 3514: GERALD07加强版 lct+可持久化线段树

    题目大意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解: 这道题考试的时候没想出来 于是便爆炸了 结果今天下午拿出昨天准备的题表准备做题的时候 题表里就有这题 ...

  9. 【62测试】【状压dp】【dfs序】【线段树】

    第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...

随机推荐

  1. 5 个最好的3D游戏开发工具(转)

    转自:http://www.open-open.com/news/view/33a4f0 5 个最好的3D游戏开发工具 jopen 2012-11-19 22:56:21 • 发布 摘要:UDK(th ...

  2. Html5 Egret游戏开发 成语大挑战(一)开篇

    最近接触了Egret白鹭引擎,感觉非常好用,提供了各种各样的开发工具让开发者和设计者更加便捷,并且基于typescript语言开发省去了很多学习成本,对于我们这种掉微软坑许久的童鞋来说,确实很有吸引力 ...

  3. blogs for learning java

    曹海成的专栏 http://blog.csdn.net/caohaicheng/article/details/38071097 http://blog.csdn.net/a5489888/artic ...

  4. SQL使用开窗函数与CTE查询每月销售额的前几名

    WITH tagTab AS( SELECT YearMonth, pm=RANK() OVER(PARTITION BY YearMonth ORDER BY amount DESC) FROM S ...

  5. Linux 网络编程详解十

    select int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *tim ...

  6. [转]C#如何把文件夹压缩打包然后下载

    public partial class _Default2 : System.Web.UI.Page{ protected void Page_Load(object sender, EventAr ...

  7. Windows数据类型

    WORD:16位无符号整形数据 DWORD:32字节无符号整型数据(DWORD32) DWORD64:64字节无符号整型数据 INT:32位有符号整型数据类型 INT_PTR:指向INT数据类型的指针 ...

  8. 让 Generator 自启动

    文章同步自个人博客:http://www.52cik.com/2016/07/11/generator-co.html 此前只是简单使用而没有真正的去研究 Generator,这次要好好折腾下这货. ...

  9. 7z压缩文件时排除指定的文件

    分享一个7z压缩文件时排除指定文件类型的命令行,感觉很有用: 7z a -t7z d:\updateCRM.7z d:\updateCRM\*.* -r -x!*.log -x!*bak a:创建压缩 ...

  10. HTTP 错误 500.24 - Internal Server Error的解决方法

    错误提示: 最可能的原因:   system.web/identity@impersonate 设置为 true. 解决办法: 现在经典模式 连微软都几乎放弃了 原设想是为iis不断升级 提供的一种兼 ...