建出点分树,每个节点维护其作为点分树上lca对子树内点的贡献,线段树维护即可,同时另开一个线段树以减掉父亲重复的贡献。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. using namespace std;
  8. #define ll long long
  9. #define N 100010
  10. char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
  11. int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
  12. int read()
  13. {
  14. int x=0,f=1;char c=getchar();
  15. while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
  16. while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
  17. return x*f;
  18. }
  19. int n,m,p[N],size[N],deep[N],fa[N][19],t;
  20. bool flag[N];
  21. struct data{int to,nxt;
  22. }edge[N<<1];
  23. void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
  24. void dfs(int k)
  25. {
  26. for (int i=p[k];i;i=edge[i].nxt)
  27. if (edge[i].to!=fa[k][0])
  28. {
  29. fa[edge[i].to][0]=k;
  30. deep[edge[i].to]=deep[k]+1;
  31. dfs(edge[i].to);
  32. }
  33. }
  34. int lca(int x,int y)
  35. {
  36. if (deep[x]<deep[y]) swap(x,y);
  37. for (int j=18;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
  38. if (x==y) return x;
  39. for (int j=18;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
  40. return fa[x][0];
  41. }
  42. int dis(int x,int y){return deep[x]+deep[y]-(deep[lca(x,y)]<<1);}
  43. namespace newtree
  44. {
  45. int rt,cnt[2],root[2][N],fa[N];
  46. struct data{int l,r,x;}tree[2][N<<7];
  47. void addedge(int x,int y){fa[y]=x;}
  48. void add(int &k,int l,int r,int p,int x,int op)
  49. {
  50. if (!k) k=++cnt[op];
  51. tree[op][k].x+=x;
  52. if (l==r) return;
  53. int mid=l+r>>1;
  54. if (p<=mid) add(tree[op][k].l,l,mid,p,x,op);
  55. else add(tree[op][k].r,mid+1,r,p,x,op);
  56. }
  57. int sum(int k,int l,int r,int x,int op)
  58. {
  59. if (!k) return 0;
  60. if (l==r) return tree[op][k].x;
  61. int mid=l+r>>1;
  62. if (x<=mid) return sum(tree[op][k].l,l,mid,x,op);
  63. else return tree[op][tree[op][k].l].x+sum(tree[op][k].r,mid+1,r,x,op);
  64. }
  65. void modify(int x,int d,int w)
  66. {
  67. add(root[0][x],0,n,0,w,0),add(root[0][x],0,n,d+1,-w,0);
  68. int i=x;
  69. while (i!=rt)
  70. {
  71. int D=dis(x,fa[i]);
  72. if (D<=d)
  73. add(root[0][fa[i]],0,n,0,w,0),add(root[0][fa[i]],0,n,d-D+1,-w,0),
  74. add(root[1][i],0,n,0,-w,1),add(root[1][i],0,n,d-D+1,w,1);
  75. i=fa[i];
  76. }
  77. }
  78. int query(int x)
  79. {
  80. int ans=0,i=x;
  81. while (i) ans+=sum(root[0][i],0,n,dis(x,i),0),ans+=sum(root[1][i],0,n,dis(x,fa[i]),1),i=fa[i];
  82. return ans;
  83. }
  84. }
  85. void make(int k,int from)
  86. {
  87. size[k]=1;
  88. for (int i=p[k];i;i=edge[i].nxt)
  89. if (!flag[edge[i].to]&&edge[i].to!=from)
  90. {
  91. make(edge[i].to,k);
  92. size[k]+=size[edge[i].to];
  93. }
  94. }
  95. int findroot(int k,int from,int s)
  96. {
  97. int mx=0;
  98. for (int i=p[k];i;i=edge[i].nxt)
  99. if (!flag[edge[i].to]&&edge[i].to!=from&&size[edge[i].to]>size[mx]) mx=edge[i].to;
  100. if ((size[mx]<<1)>s) return findroot(mx,k,s);
  101. else return k;
  102. }
  103. int build(int k)
  104. {
  105. make(k,k);
  106. flag[k=findroot(k,k,size[k])]=1;
  107. for (int i=p[k];i;i=edge[i].nxt)
  108. if (!flag[edge[i].to]) newtree::addedge(k,build(edge[i].to));
  109. return k;
  110. }
  111. int main()
  112. {
  113. #ifndef ONLINE_JUDGE
  114. freopen("bzoj4372.in","r",stdin);
  115. freopen("bzoj4372.out","w",stdout);
  116. const char LL[]="%I64d\n";
  117. #else
  118. const char LL[]="%lld\n";
  119. #endif
  120. n=read(),m=read();
  121. for (int i=1;i<n;i++)
  122. {
  123. int x=read(),y=read();
  124. addedge(x,y),addedge(y,x);
  125. }
  126. fa[1][0]=1;dfs(1);
  127. for (int j=1;j<19;j++)
  128. for (int i=1;i<=n;i++)
  129. fa[i][j]=fa[fa[i][j-1]][j-1];
  130. newtree::rt=build(1);
  131. while (m--)
  132. {
  133. char c=getc();
  134. if (c=='M')
  135. {
  136. int x=read(),d=read(),w=read();
  137. newtree::modify(x,d,w);
  138. }
  139. else printf("%d\n",newtree::query(read()));
  140. }
  141. return 0;
  142. }

  

BZOJ4372 烁烁的游戏(动态点分治+线段树)的更多相关文章

  1. BZOJ4372烁烁的游戏——动态点分治+线段树(点分树套线段树)

    题目描述 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠.皮皮鼠会被 ...

  2. [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]

    题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...

  3. [BZOJ4372]烁烁的游戏(动态点分治+线段树)

    和[BZOJ3730]震波几乎一样,每个点建两棵线段树分别代表它的管辖范围内以它为LCA的路径的贡献和它对父亲的贡献. 注意点分树上的点的距离在原树上不单调,所以不能有若距离超出限制就break之类的 ...

  4. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...

  5. bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树

    [Submit][Status][Discuss] Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳 ...

  6. BZOJ4372: 烁烁的游戏(动态点分治)

    Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮 ...

  7. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  8. 【bzoj3730】震波 动态点分治+线段树

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  9. 2019ICPC上海网络赛 A Lightning Routing I 点分树(动态点分治)+线段树

    题意 给一颗带边权的树,有两种操作 \(C~e_i~w_i\),将第\(e_i\)条边的边权改为\(w_i\). \(Q~v_i\),询问距\(v_i\)点最远的点的距离. 分析 官方题解做法:动态维 ...

随机推荐

  1. day86

    视图组件 基于以往我们所用的视图函数,我们发现其中冗余的代码比较多,今天就来对其进行封装,争取做一个代码洁癖者 原来我们的视图函数: class Book(APIView): def get(self ...

  2. eclipse中使用svn提交,更新代码。

    在新公司工作,版本管理工具变成了svn,之前一直用git作为版本管理,用的编辑IDE是IntelliJIDEA,在这个编辑器下工作,还是很方便的,但是现在使用eclipse和svn.有点不习惯,但还是 ...

  3. Git .gitignore文件的使用

    本文转载自 http://blog.csdn.net/xmyzlz/article/details/8592302 在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改 .giti ...

  4. vue 中使用iconfont Unicode编码线上字体图标的流程

    1.打开http://www.iconfont.cn官网,搜索你想要的图标.添加字体图标到购物车,点击购物车然后添加至项目,点击确定 2.点击图标管理/我的项目,找到对应的文件,点击Unicode,然 ...

  5. 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)

    首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...

  6. Jlink使用技巧之虚拟串口功能

    前言 串口调试是单片机开发过程必不可少的一个功能,一般是使用一个UART-TTL的串口模块来实现串口的功能,其实下载调试使用的Jlink仿真器也可以实现串口调试的功能,本篇文章将介绍如何使用Jlink ...

  7. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十二)Spring集成Redis缓存

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 整合Redis 本来以为类似的Redis教程和整合代码应该会很多,因 ...

  8. Linux 小记 — Ubuntu 自动化配置

    前言 工欲善其事,必先利其器.经过多次的重复配置 ubuntu 开发坏境,我终于决定花点时间总结一下,并将其写成一个自动化配置脚本.服务器实例:ubuntu 16.04,技术栈:shell,pytho ...

  9. Webpack 2 视频教程 007 - 配置 WDS 进行浏览器自动刷新

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  10. python基础学习笔记(十三)

    re模块包含对 正则表达式.本章会对re模块主要特征和正则表达式进行介绍. 什么是正则表达式 正则表达式是可以匹配文本片段的模式.最简单的正则表达式就是普通字符串,可以匹配其自身.换包话说,正则表达式 ...