bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. At the very begining, the i-th vertex is assigned with weight w i.

There are q operations. Each operations are of the following 2 types:

Change the weight of vertex v into x (denoted as "! v x"),
Ask the total weight of vertices whose distance are no more than d away from vertex v (denoted as "? v d").

Note that the distance between vertex u and v is the number of edges on the shortest path between them.

InputThe input consists of several tests. For each tests:

The first line contains n,q (1≤n,q≤10 5). The second line contains n integers w 1,w 2,…,w n (0≤w i≤10 4). Each of the following (n - 1) lines contain 2 integers a i,b i denoting an edge between vertices a i and b i (1≤a i,b i≤n). Each of the following q lines contain the operations (1≤v≤n,0≤x≤10 4,0≤d≤n).
OutputFor each tests:

For each queries, a single number denotes the total weight.Sample Input

  1. 4 3
  2. 1 1 1 1
  3. 1 2
  4. 2 3
  5. 3 4
  6. ? 2 1
  7. ! 1 0
  8. ? 2 1
  9. 3 3
  10. 1 2 3
  11. 1 2
  12. 1 3
  13. ? 1 0
  14. ? 1 1
  15. ? 1 2

Sample Output

  1. 3
  2. 2
  3. 1
  4. 6
  5. 6

  1. 题意:给你一棵树,N个点,每个点一个权值,然后Q组操作(共两种),第一种是求导一个节点距离不超过d的所有点的权值和是多少;第二种操作时,修改一个点的权值;
    题解:多次进行操作1。此时不能每次都ONlogN)了,太慢了。我们考虑到对于点分治,树的重心一共有logN层,第一层为整棵树的重心,第二层为第一层重心的子树的重心,以此类推,每次至少分成两个大小差不多的子树,所以
    一共有logN层。而且,对于一个点,他最多只属于logN个子树,也就是最多只属于logN个重心。所以我们可以预处理出每个点所属于的重心以及到这些重心的距离,以每个重心建树状数组,每个点按照到重心的距离插入到树状数组中,
    然后每次查询到u距离不超过d的点的个数就通过树状数组求前缀和得到。假设一个重心xu的距离为dis,那么便统计到重心x距离不超过d-dis的点的个数,这个过程我们称之为“借力”,本身能力有限,所以需要借助x的影响力。因为
    如果这个重心被u借力了,那么这个重心的子重心一定也被借力,由于相邻被借力的两个重心xy所统计的点会有重复,所以我们需要去重。去重的话我们就通过对每个节点再开一个vx的树状数组,这个树状数组的意义为:重心x的子
    v的重心为y时,子树v中每个点到x的距离为下标建立的树状数组。因为重心x与重心y交集的部分,重心x包括的部分重心y一定包括,所以统计的时候减去vx的树状数组中距x不超过d-dis的点的个数即可。访问u所属与的所有重心,
    挨个借力,同时去重,便能得到距离u不超过d的点的个数。因为重心最多logN层,每个树状数组最多N个点,logN复杂度的统计,所以每次查询复杂度OlogN*logN)。我们最多为每个节点开2个树状数组,而且每一层所有树状数组的
    大小相加不超过N,所以树状数组的占用空间为O2NlogN)。
    在上面的基础上稍做扩充。预处理的时候插入树状数组的就是该点的权值,查询依旧是统计前缀和。修改点权值的时候,便是和查询一样,在u距重心x距离d的位置在x的树状数组中修改u的权值,同时修改u属于重心x的子树vvx的树
    状数组中相同位置的值。复杂度和查询一样为OlogN*logN)。
  1. 参考代码:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define pii pair<int,int>
  4. #define mkp make_pair
  5. #define lowbit(x) (x&-x)
  6.  
  7. typedef long long ll;
  8. const int INF=0x3f3f3f3f;
  9. const int maxn=1e5+;
  10. int n,q,w[maxn];
  11. char op[];
  12. struct MSG{
  13. int id1,id2;
  14. int dep;
  15. } msg[maxn][];
  16. struct Edge{
  17. int v,nxt;
  18. } edge[maxn<<];
  19. int vis[maxn],head[maxn],tot;
  20. int root,siz[maxn],mx[maxn],fa[maxn],S;
  21. int maxfloor[maxn],idn,L[maxn<<],R[maxn<<];
  22. int c[maxn*];
  23. void Init()
  24. {
  25. S=n;idn=;
  26. tot=root=;
  27. memset(c,,sizeof c);
  28. memset(vis,,sizeof vis);
  29. memset(w,,sizeof w);
  30. memset(head,-,sizeof head);
  31. memset(msg,,sizeof msg);
  32. }
  33. void AddEdge(int x,int y)
  34. {
  35. edge[tot].v=y;
  36. edge[tot].nxt=head[x];
  37. head[x]=tot++;
  38. }
  39.  
  40. void Add(int l,int r,int pos,int val)
  41. {
  42. while(pos<r-l)
  43. c[l+pos]+=val,pos+=lowbit(pos);
  44. }
  45. int Sum(int l,int r,int len)
  46. {
  47. if(len<) return ;
  48. if(len>r-l-) len=r-l-;
  49. int res=;
  50. while(len) res+=c[l+len],len-=lowbit(len);
  51. return res;
  52. }
  53.  
  54. void getroot(int u,int fa)
  55. {
  56. siz[u]=;mx[u]=;
  57. for(int i=head[u];~i;i=edge[i].nxt)
  58. {
  59. int v=edge[i].v;
  60. if(vis[v]||v==fa) continue;
  61. getroot(v,u);
  62. siz[u]+=siz[v];
  63. mx[u]=max(mx[u],siz[v]);
  64. }
  65. mx[u]=max(mx[u],S-siz[u]);
  66. if(mx[u]<mx[root]) root=u;
  67. }
  68.  
  69. int getmaxdep(int u,int fa)
  70. {
  71. int res=;
  72. for(int i=head[u];~i;i=edge[i].nxt)
  73. {
  74. int v=edge[i].v;
  75. if(vis[v]||v==fa) continue;
  76. res=max(res,+getmaxdep(v,u));
  77. }
  78. return res;
  79. }
  80. void dfs(int u,int fa,int deep,int id,int flor,int tp)
  81. {
  82. if(!tp) msg[u][flor].id1=id;
  83. else msg[u][flor].id2=id;
  84. msg[u][flor].dep=deep;
  85. Add(L[idn],R[idn],deep,w[u]);
  86. for(int i=head[u];~i;i=edge[i].nxt)
  87. {
  88. int v=edge[i].v;
  89. if(!vis[v]&&v!=fa) dfs(v,u,deep+,id,flor,tp);
  90. }
  91. }
  92. void solve(int u,int s,int flor)
  93. {
  94. vis[u]=; maxfloor[u]=flor;
  95. idn++; L[idn]=R[idn-];
  96. R[idn]=L[idn]+getmaxdep(u,)+;
  97. dfs(u,,,idn,flor,);
  98. msg[u][flor].id2=-;
  99. for(int i=head[u];~i;i=edge[i].nxt)
  100. {
  101. int v=edge[i].v;
  102. if(vis[v]) continue;
  103. idn++;L[idn]=R[idn-];
  104. R[idn]=L[idn]+getmaxdep(v,u)+;
  105. dfs(v,u,,idn,flor,);
  106. }
  107.  
  108. for(int i=head[u];~i;i=edge[i].nxt)
  109. {
  110. int v=edge[i].v;
  111. if(vis[v]) continue;
  112. S=siz[v]; root=;
  113. if(siz[v]>siz[u]) S=s-siz[u];
  114. getroot(v,u);
  115. solve(root,siz[v],flor+);
  116. }
  117. }
  118.  
  119. int main()
  120. {
  121. while(~scanf("%d%d",&n,&q))
  122. {
  123. Init();
  124. for(int i=;i<=n;++i) scanf("%d",w+i);
  125. for(int i=;i<n;++i)
  126. {
  127. int x,y;
  128. scanf("%d%d",&x,&y);
  129. AddEdge(x,y);AddEdge(y,x);
  130. }
  131. mx[root]=INF;
  132. getroot(,);
  133. solve(,S,);
  134. while(q--)
  135. {
  136. int x,y,ans;
  137. scanf("%s%d%d",&op,&x,&y);
  138. if(op[]=='?')
  139. {
  140. ans=;
  141. for(int f=;f<=maxfloor[x];++f)
  142. {
  143. int id1=msg[x][f].id1;
  144. int id2=msg[x][f].id2;
  145. int dep=msg[x][f].dep;
  146. ans+=Sum(L[id1],R[id1],y+-dep);
  147. if(id2!=-) ans-=Sum(L[id2],R[id2],y+-dep);
  148. }
  149. printf("%d\n",ans);
  150. }
  151. else
  152. {
  153. for(int f=;f<=maxfloor[x];++f)
  154. {
  155. int id1=msg[x][f].id1;
  156. int id2=msg[x][f].id2;
  157. int dep=msg[x][f].dep;
  158. Add(L[id1],R[id1],dep,y-w[x]);
  159. if(id2!=-) Add(L[id2],R[id2],dep,y-w[x]);
  160. }
  161. w[x]=y;
  162. }
  163. }
  164. }
  165.  
  166. return ;
  167. }

HDU4918 Query on the subtree 点分治+树状数组的更多相关文章

  1. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  2. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  3. 【bzoj3262】陌上花开 CDQ分治+树状数组

    题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...

  4. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

  5. LOJ3146 APIO2019路灯(cdq分治+树状数组)

    每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...

  6. BZOJ_3262_陌上花开_CDQ分治+树状数组

    BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...

  7. BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组

    BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后, ...

  8. BZOJ_3295_[Cqoi2011]动态逆序对_CDQ分治+树状数组

    BZOJ_3295_[Cqoi2011]动态逆序对_CDQ分治+树状数组 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一 ...

  9. BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组

    BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组 Description        给定N个数对(xi, yi),求最长上升子 ...

随机推荐

  1. 腾讯Techo开发者大会PPT分享

    腾讯云年度的开发者大会已经落幕,大会包括1场前沿技术主峰会,18个技术专场,150位海内外技术专家,28个互动展区,8场动手实验室,23小时小程序云开发极限编程,1场数据库诊断大赛. 内容上涵盖了最新 ...

  2. ubantu14.04安装storm伪分布式

    1.安装jdk 安装:sudo apt-get install openjdk-7-jdk 配置: 修改文件 sudo nano /etc/profile , 添加以下内容: 立即执行使之生效: 2. ...

  3. RHEL7.2 安装Eclipse-oxygen Hadoop开发环境

    1 Eclipse-oxygen下载地址 http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/re ...

  4. Install Elastic stack

    1. 安装环境 系统版本:centos 6.9 java版本:1.8.0_181 程序版本:6.6 (整个stack需保持相同的版本) 2. 安装顺序 1 Elasticsearch 2 Kibana ...

  5. linux终端操作

    ------------恢复内容开始------------ tab键自动补全 ls列出当前文件目录: 默认是当前目录 “.”代表当前目录 “..”代表父目录 -a显示所有,而隐藏文件的第一字符为点“ ...

  6. 10分钟学会Python函数基础知识

    看完本文大概需要8分钟,看完后,仔细看下代码,认真回一下,函数基本知识就OK了.最好还是把代码敲一下. 一.函数基础 简单地说,一个函数就是一组Python语句的组合,它们可以在程序中运行一次或多次运 ...

  7. Java中的集合(Set,List,Map)

    ******************collections类总结*************************** JAVA集合主要分为三种类型:    Set(集)    List(列表)    ...

  8. CentOS 7 安装 bind 服务 实现内网DNS

    目录 安装 配置 服务管理 测试 安装 废话不多说,直接安装 yum install -y bind bind-utils 配置 [root@jenkins named]# rpm -ql bind ...

  9. AJAX与Django

    AJAX 什么是AJAX? AJAX不是JavaScript的规范,它的缩写:Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求.提交任务之 ...

  10. shell脚本中的逻辑判断、文件目录属性判断、if特殊用法、case判断

    7月12日任务 20.5 shell脚本中的逻辑判断20.6 文件目录属性判断20.7 if特殊用法20.8/20.9 case判断 20.5 shell脚本中的逻辑判断 逻辑判断在shell中随处可 ...