BZOJ

洛谷

\(Description\)

给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数。

\(n,q\leq3\times10^5\)。

\(Solution\)

\(p,a,b\)都在一条链上。

那么如果\(a\)是\(p\)的祖先,答案就是\(\min(dep[p],\ k)*(sz[p]-1)\)。可以\(O(1)\)计算。

如果\(a\)在\(p\)的子树中,答案就是\(\sum_{dis(a,p)\leq k}sz[a]-1\)。

对于第二种情况,实际就是对深度在\(dep[p]\sim dep[p]+k\)且处于\(p\)子树内的点的\(size\)求和。

以\(dep\)为下标,就是对\(p\)子树区间求和了。可以主席树/线段树合并。时空复杂度\(O(n\log n)\)。

也可以用树状数组维护深度为\(x\)的所有点的\(size\)和。类似天天爱跑步,在进入一棵子树时把\(Ans\)减去\(sum(dep[p],dep[p]+k)\),离开这棵子树时把\(Ans\)再加上\(sum(dep[p],dep[p]+k)\),就可以得到这棵子树的答案\(Ans\)了。

时间复杂度\(O(n\log n)\)。

用到的数组下标是深度,所以可以试下长链剖分。同样\(f[x][i]\)表示以\(x\)为根深度为\(i\)的点的\(size\)和。

长链剖分每次继承重儿子要把数组后移一位,而我们要求区间和,这样前缀和就不好维护了。但是我们可以维护后缀和。

复杂度\(O(n)\)。

为啥洛谷加了fread慢好多啊==

  1. //36944kb 3808ms
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <algorithm>
  5. //#define gc() getchar()
  6. #define MAXIN 300000
  7. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  8. typedef long long LL;
  9. const int N=3e5+5;
  10. int sz[N],dep[N],mxd[N],son[N],pos[N];
  11. LL Ans[N],f[N];//f:后缀和 //LL!
  12. char IN[MAXIN],*SS=IN,*TT=IN;
  13. struct Edge
  14. {
  15. int Enum,H[N],nxt[N<<1],to[N<<1];
  16. inline void AE(int u,int v)
  17. {
  18. to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
  19. to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
  20. }
  21. }T;
  22. struct Quries
  23. {
  24. int Enum,H[N],nxt[N],id[N],k[N];
  25. inline void AE(int ID,int K,int u)
  26. {
  27. id[++Enum]=ID, k[Enum]=K, nxt[Enum]=H[u], H[u]=Enum;
  28. }
  29. }Q;
  30. inline int read()
  31. {
  32. int now=0;register char c=gc();
  33. for(;!isdigit(c);c=gc());
  34. for(;isdigit(c);now=now*10+c-'0',c=gc());
  35. return now;
  36. }
  37. void DFS1(int x,int fa)
  38. {
  39. int mx=-1;/*-1!*/ sz[x]=1;
  40. for(int i=T.H[x],v; i; i=T.nxt[i])
  41. if((v=T.to[i])!=fa)
  42. dep[v]=dep[x]+1, DFS1(v,x), sz[x]+=sz[v], mxd[v]>mx&&(mx=mxd[v],son[x]=v);
  43. mxd[x]=mx+1;
  44. }
  45. void DFS2(int x,int fa)
  46. {
  47. static int Index=0;
  48. int px=pos[x]=++Index;// f[px]=sz[x]-1;
  49. if(!son[x]) return;
  50. DFS2(son[x],x), f[px]+=f[px+1];
  51. for(int i=T.H[x],v; i; i=T.nxt[i])
  52. if((v=T.to[i])!=fa && v!=son[x])
  53. {
  54. DFS2(v,x); int pv=pos[v];
  55. for(int j=0,lim=mxd[v]; j<lim; ++j) f[px+j+1]+=f[pv+j];
  56. f[px]+=f[pv];
  57. }
  58. LL sum=f[px];
  59. for(int i=Q.H[x],mx=mxd[x]; i; i=Q.nxt[i])
  60. {
  61. int k=Q.k[i],id=Q.id[i];
  62. Ans[id]=1ll*std::min(dep[x],k)*(sz[x]-1)+sum-(k>=mx?0:f[px+k+1]);
  63. }
  64. f[px]+=sz[x]-1;
  65. }
  66. int main()
  67. {
  68. int n=read(),q=read();
  69. for(int i=1; i<n; ++i) T.AE(read(),read());
  70. for(int i=1; i<=q; ++i) Q.AE(i,read(),read());
  71. DFS1(1,1), DFS2(1,1);
  72. for(int i=1; i<=q; ++i) printf("%lld\n",Ans[i]);
  73. return 0;
  74. }

BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)的更多相关文章

  1. BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)

    题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...

  2. BZOJ.3252.攻略(贪心 长链剖分/线段树)

    题目链接 贪心,每次选价值最大的一条到根的链.比较显然(不选白不选). 考虑如何维护这个过程.一个点的价值选了就没有了,而它只会影响它子树里的点,可以用DFS序+线段树修改.而求最大值也可以用线段树. ...

  3. [WC2010]重建计划(长链剖分+线段树+分数规划)

    看到平均值一眼分数规划,二分答案mid,边权变为w[i]-mid,看是否有长度在[L,R]的正权路径.设f[i][j]表示以i为根向下j步最长路径,用长链剖分可以优化到O(1),查询答案线段树即可,复 ...

  4. 2018牛客网暑假ACM多校训练赛(第七场)I Tree Subset Diameter 动态规划 长链剖分 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round7-I.html 题目传送门 -  https://www.n ...

  5. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  6. 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)

    传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...

  7. 洛谷 P4292 - [WC2010]重建计划(长链剖分+线段树)

    题面传送门 我!竟!然!独!立!A!C!了!这!道!题!incredible! 首先看到这类最大化某个分式的题目,可以套路地想到分数规划,考虑二分答案 \(mid\) 并检验是否存在合法的 \(S\) ...

  8. Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)

    F. Dominant Indices 题意: 给一颗无向树,根为1.对于每个节点,求其子树中,哪个距离下的节点数量最多.数量相同时,取较小的那个距离. 题目: 这类题一般的做法是树上的启发式合并,复 ...

  9. P4292-[WC2010]重建计划【长链剖分,线段树,0/1分数规划】

    正题 题目链接:https://www.luogu.com.cn/problem/P4292 题目大意 给出\(n\)个点的一棵树,然后求长度在\([L,U]\)之间的一条路径的平均权值最大. 解题思 ...

随机推荐

  1. 基于concurrent.futures的进程池 和线程池

    concurrent.futures:是关于进程池 和 线程池 的 官方文档 https://docs.python.org/dev/library/concurrent.futures.html 现 ...

  2. python 之 列表与字典

    1.4 列表与字典 列表与字典,这两种类型,都是各种类型的集合,以列表为例,如果列表中包含列表,就形成嵌套. 这两种类型几乎是所有python脚本的主要工作组件 . 这种结构信息是可变的可修改的.不像 ...

  3. 阿里云服务器 http 转 https

    转载: http://blog.csdn.net/zzp961224/article/details/78934310 做个笔记 以备遗忘. 环境: 阿里云云服务器    Windows Server ...

  4. CA认证的原理和流程及https原理

    1.什么是CA证书. 看过一些博客,写的比较形象具体. ◇ 普通的介绍信 想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 B 公司的所有人都不认识他,他咋办捏?常 ...

  5. python内置的魔术命令(builtin magic commands)

    在ipython或者jupyter notebook中,会出现"%"开头并且一个很短的命令,例如交互式的matlablib绘图: %matplotlib inline 之前一直不知 ...

  6. Asp.NetCore 读取配置文件帮助类

    /// <summary> /// 读取配置文件信息 /// </summary> public class ConfigExtensions { public static ...

  7. Swap file ".hive-site.xml.swp" already exists

    1.使用命令[hadoop@slaver1 conf]$ ls -la查找出隐藏文件,然后删除报出来的错误文件. [hadoop@slaver1 conf]$ rm -rf .hive-site.xm ...

  8. Scala学习教程笔记一之基础语法,条件控制,循环控制,函数,数组,集合

    前言:Scala的安装教程:http://www.cnblogs.com/biehongli/p/8065679.html 1:Scala之基础语法学习笔记: :声明val变量:可以使用val来声明变 ...

  9. javaScript事件(八)事件类型之变动事件

    DOM2级的变动(mutation)事件能在DOM中某一部分发送变化时给出提示.变动事件为XML或HTML DOM设计的,并不特定于某种语言.DOM2级定义了如下变动事件. DOMSubtreeMod ...

  10. Appearance-and-Relation Networks for Video Classification论文笔记 (ARTnet)

    ARTnet: caffe实现:代码 1 Motivation:How to model appearance and relation (motion) 主要工作是在3D卷积的基础上,提升了acti ...