ZJOI 2008 树上的统计

一树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w。我们将以下面的形式来要求你对这棵树完成一些操作:

  1. CHANGE u t :把节点 u 权值改为t;
  2. QMAX u v :询问点 u 到点 v 路径上的节点的最大权值;
  3. QSUM u v :询问点 u 到点 v 路径上的节点的权值和。

注意:从点 u 到点 v 路径上的节点包括 u 和 v 本身。

输入格式

第一行为一个数 n,表示节点个数;

接下来 n-1 行,每行两个整数 a,b,表示节点 a与节点 b 之间有一条边相连;

接下来 n 行,每行一个整数,第 i 行的整数 wi​ 表示节点i 的权值;

接下来一行,为一个整数 q ,表示操作总数;

接下来 q 行,每行一个操作,以 CHANGE u t 或 QMAX u v 或 QSUM u v的形式给出。

输出格式

对于每个 QMAX 或 QSUM 的操作,每行输出一个整数表示要求的结果。

样例

样例输入

  1. 4
  2. 1 2
  3. 2 3
  4. 4 1
  5. 4 2 1 3
  6. 12
  7. QMAX 3 4
  8. QMAX 3 3
  9. QMAX 3 2
  10. QMAX 2 3
  11. QSUM 3 4
  12. QSUM 2 1
  13. CHANGE 1 5
  14. QMAX 3 4
  15. CHANGE 3 6
  16. QMAX 3 4
  17. QMAX 2 4
  18. QSUM 3 4

样例输出

  1. 4
  2. 1
  3. 2
  4. 2
  5. 10
  6. 6
  7. 5
  8. 6
  9. 5
  10. 16

数据范围与提示

对于 100% 的数据,有1≤n≤3×10^4,0≤q≤2×10^5。中途操作中保证每个节点的权值 w 在 −30000 至 30000 之间。

_______________________________________________________________________________________

很简单的树剖,好久没有写了,第一次写的不知道哪里错了,还是写了第二次!

_______________________________________________________________________________________

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 typedef long long ll;
  4. 4 const ll maxn=30020;
  5. 5 ll n,m;
  6. 6 struct edge
  7. 7 {
  8. 8 ll u,v,nxt;
  9. 9 }e[maxn<<1];
  10. 10 ll head[maxn],js;
  11. 11 void addage(ll u,ll v)
  12. 12 {
  13. 13 e[++js].u=u;e[js].v=v;
  14. 14 e[js].nxt=head[u];head[u]=js;
  15. 15 }
  16. 16 ll w[maxn];
  17. 17 ll dep[maxn],fat[maxn],siz[maxn],son[maxn];
  18. 18 void dfs(ll u,ll fa)
  19. 19 {
  20. 20 dep[u]=dep[fa]+1;
  21. 21 fat[u]=fa;
  22. 22 siz[u]=1;
  23. 23 for(ll i=head[u];i;i=e[i].nxt)
  24. 24 {
  25. 25 ll v=e[i].v;
  26. 26 if(v==fa)continue;
  27. 27 dfs(v,u);
  28. 28 siz[u]+=siz[v];
  29. 29 if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
  30. 30 }
  31. 31 }
  32. 32 ll pos[maxn],top[maxn],fos[maxn],p;
  33. 33 void getpos(ll u,ll fa)
  34. 34 {
  35. 35 top[u]=fa;
  36. 36 pos[u]=++p;
  37. 37 fos[p]=u;
  38. 38 if(!son[u])return ;
  39. 39 getpos(son[u],fa);
  40. 40 for(ll i=head[u];i;i=e[i].nxt)
  41. 41 {
  42. 42 ll v=e[i].v;
  43. 43 if(v!=son[u] && v!=fat[u])getpos(v,v);
  44. 44 }
  45. 45 }
  46. 46 ll MAX,SUM;
  47. 47 ll _sum[maxn<<2],_max[maxn<<2];
  48. 48 void update(ll cur)
  49. 49 {
  50. 50 _sum[cur]=_sum[cur<<1]+_sum[cur<<1|1];
  51. 51 _max[cur]=max(_max[cur<<1],_max[cur<<1|1]);
  52. 52 }
  53. 53 void build(ll cur,ll l,ll r)
  54. 54 {
  55. 55 if(l==r)
  56. 56 {
  57. 57 _sum[cur]=_max[cur]=w[fos[l]];
  58. 58 return ;
  59. 59 }
  60. 60 ll mid=(l+r)>>1;
  61. 61 build(cur<<1,l,mid);
  62. 62 build(cur<<1|1,mid+1,r);
  63. 63 update(cur);
  64. 64 }
  65. 65 void query(ll cur,ll l,ll r,ll ql,ll qr)
  66. 66 {
  67. 67 if(ql<=l && r<=qr)
  68. 68 {
  69. 69 MAX=max(_max[cur],MAX);
  70. 70 SUM+=_sum[cur];
  71. 71 return ;
  72. 72 }
  73. 73 ll mid=(l+r)>>1;
  74. 74 if(ql<=mid)query(cur<<1,l,mid,ql,qr);
  75. 75 if(qr>mid)query(cur<<1|1,mid+1,r,ql,qr);
  76. 76 }
  77. 77 void ask(ll u,ll v)
  78. 78 {
  79. 79 ll tpu=top[u],tpv=top[v];
  80. 80 while(tpu!=tpv)
  81. 81 {
  82. 82 if(dep[tpu]<dep[tpv])
  83. 83 {
  84. 84 swap(u,v);swap(tpu,tpv);
  85. 85 }
  86. 86 query(1,1,n,pos[tpu],pos[u]);
  87. 87 u=fat[tpu];tpu=top[u];
  88. 88 }
  89. 89 if(dep[u]>dep[v])swap(u,v);
  90. 90 query(1,1,n,pos[u],pos[v]);
  91. 91 }
  92. 92 void change(ll cur,ll l,ll r,ll p,ll x)
  93. 93 {
  94. 94 if(l==r)
  95. 95 {
  96. 96 _max[cur]=_sum[cur]=x;
  97. 97 return ;
  98. 98 }
  99. 99 ll mid=(l+r)>>1;
  100. 100 if(p<=mid)change(cur<<1,l,mid,p,x);
  101. 101 else change(cur<<1|1,mid+1,r,p,x);
  102. 102 update(cur);
  103. 103 }
  104. 104 int main()
  105. 105 {
  106. 106 scanf("%lld",&n);
  107. 107 for(ll i=1,u,v;i<n;++i)
  108. 108 {
  109. 109 scanf("%lld%lld",&u,&v);
  110. 110 addage(u,v);addage(v,u);
  111. 111 }
  112. 112 for(int i=1;i<=n;++i)scanf("%lld",w+i);
  113. 113 scanf("%lld",&m);
  114. 114 dfs(1,0);
  115. 115 getpos(1,1);
  116. 116 build(1,1,n);
  117. 117 char s[10];
  118. 118 ll u,v;
  119. 119 while(m--)
  120. 120 {
  121. 121 scanf("%s%lld%lld",s,&u,&v);
  122. 122 if(s[1]=='H')change(1,1,n,pos[u],v);
  123. 123 else
  124. 124 {
  125. 125 MAX=-0x7fffffff,SUM=0;
  126. 126 ask(u,v);
  127. 127 printf("%lld\n",s[1]=='M'?MAX:SUM);
  128. 128 }
  129. 129 }
  130. 130 return 0;
  131. 131 }

LOJ10138的更多相关文章

随机推荐

  1. MySQL中的模糊查询 like 和 Oracle中的 instr() 函数有同样的查询效果

    注:MySQL中的模糊查询 like 和 Oracle中的 instr() 函数有同样的查询效果: 如下所示: MySQL: select * from tableName where name li ...

  2. Eureka Server启动过程分析

    1.首先,SpringCloud充分利用了SpringBoot的自动装配特点 eureka-server的jar包,发现在META-INF下面的配置文件spring.factories,里面记录了Sp ...

  3. 第十五章节 BJROBOT cartographer 算法构建地图【ROS全开源阿克曼转向智能网联无人驾驶车】

    建地图前说明:请确保你的小车已经校正好 IMU.角速度.线速度,虚拟机配置好 ROS 网络的前提进行,否则会造成构建地图无边界.虚拟机端无法正常收到小车主控端发布的话题数据等异常情况!! 1.把小车平 ...

  4. linux based bottlerocket-os

    linux based bottlerocket-os 概要 aws开源,专注与运行容器的linux os 参看 https://github.com/bottlerocket-os

  5. Beta冲刺——第五天

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  6. ES6 proxy代理详解及用法

    proxy官方的详细解释为代理器,个人理解为相当于一个拦截器,外部的所有访问必须先通过这层拦截,监视到对象的读写过程,因此提供了这 种机制对外部的访问进行过滤和修改. 上述例子为proxy new一个 ...

  7. RewriteCond 和RewriteRule规则说明 (转)

    Apache的Mod_rewrite学习 (RewriteCond重写规则的条件)收藏RewriteCond Syntax: RewriteCond TestString CondPattern [f ...

  8. MATLAB在读取excel文件是发生错误,怎么解决?

    转载:https://blog.csdn.net/qq_38712026/article/details/78783422?utm_source=blogxgwz4

  9. Sql Server Sum函数的特殊使用

    利用Sql Server的Sum函数开窗得到累计值 具体详解https://www.cnblogs.com/zhaoshujie/p/9594676.html 个人示例例子 DECLARE @Sale ...

  10. phpstorm 注册码破解

    激活码1 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGljZW5zZWVOYW1lIjoi5q2j54mIIOaOiOadgyIsImFzc2ln ...