原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html

题目传送门 - BZOJ3052

题目传送门 - UOJ#58

题意

  给定一棵树,有 $n$ 个节点。有 $m$ 种颜色,第 $i$ 个节点的颜色为 $c_i$ 。

  给定参数 $v_{1},v_2,\cdots,v_m$ 和 $w_1,w_2,\cdots ,w_n$ ,具有以下意义:

    第 $i$ 次遇到颜色为 $j$ 的节点,新得到的收益为 $v_{j}\times w_i$ 。

  现在有 $q$ 次操作,操作有以下两种类型:

  1. 给定 $x,y$ ,询问一个人从节点 $x$ 走到节点 $y$ 得到的总收益。

  2. 给定 $x,y$ ,把节点 $x$ 的颜色改成 $y$ 。

  请你对于每一个询问输出结果。

  $1\leq n,m,q\leq 10^5,1\leq v_i,w_i\leq 10^6\ \ \ \ \ \ \ \rm{Time\ limit = 8s} $

题解

  树上带修莫队模板题。

  把树上询问转化成括号序列,变成区间问题。然后上带修莫队。

  注意询问的时候的特殊情况,例如 $x$ 和 $y$ 存在子孙或祖先关系时,括号序列区间的取值有所不同。

  时间复杂度 $O(n^\frac{5}{3})$ 。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. int read(){
  5. char ch=getchar();
  6. int x=0;
  7. while (!isdigit(ch))
  8. ch=getchar();
  9. while (isdigit(ch))
  10. x=(x<<1)+(x<<3)+ch-48,ch=getchar();
  11. return x;
  12. }
  13. const int N=100005;
  14. struct Gragh{
  15. static const int M=N*2;
  16. int cnt,y[M],nxt[M],fst[N];
  17. void clear(){
  18. cnt=0;
  19. memset(fst,0,sizeof fst);
  20. }
  21. void add(int a,int b){
  22. y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
  23. }
  24. }g;
  25. struct Query{
  26. int L,R,id,LCA;
  27. LL ans;
  28. Query(){}
  29. Query(int _L,int _R,int _id,int _LCA){
  30. L=_L,R=_R,id=_id,LCA=_LCA;
  31. }
  32. }Q[N];
  33. struct Operation{
  34. int x,v1,v2,id;
  35. Operation(){}
  36. Operation(int _x,int _v1,int _v2,int _id){
  37. x=_x,v1=_v1,v2=_v2,id=_id;
  38. }
  39. }O[N];
  40. int n,m,q,Qcnt,Ocnt;
  41. int depth[N],fa[N][20],in[N],out[N],id[N<<1],bID[N<<1],Time;
  42. int v[N],w[N],c[N],dc[N];
  43. int tax[N],opt[N];
  44. void dfs(int x,int pre,int d){
  45. fa[x][0]=pre,depth[x]=d,id[in[x]=++Time]=x;
  46. for (int i=1;i<17;i++)
  47. fa[x][i]=fa[fa[x][i-1]][i-1];
  48. for (int i=g.fst[x];i;i=g.nxt[i])
  49. if (g.y[i]!=pre)
  50. dfs(g.y[i],x,d+1);
  51. id[out[x]=++Time]=x;
  52. }
  53. int LCA(int x,int y){
  54. if (depth[x]<depth[y])
  55. swap(x,y);
  56. for (int i=16;i>=0;i--)
  57. if (depth[x]-(1<<i)>=depth[y])
  58. x=fa[x][i];
  59. if (x==y)
  60. return x;
  61. for (int i=16;i>=0;i--)
  62. if (fa[x][i]!=fa[y][i])
  63. x=fa[x][i],y=fa[y][i];
  64. return fa[x][0];
  65. }
  66. bool cmp(Query a,Query b){
  67. if (bID[a.L]!=bID[b.L])
  68. return bID[a.L]<bID[b.L];
  69. if (bID[a.R]!=bID[b.R])
  70. return bID[a.R]<bID[b.R];
  71. return a.id<b.id;
  72. }
  73. bool cmpid(Query a,Query b){
  74. return a.id<b.id;
  75. }
  76. LL ans=0;
  77. void update(int i){
  78. int x=id[i];
  79. if (!opt[x])
  80. ans+=1LL*v[c[x]]*w[++tax[c[x]]];
  81. else
  82. ans-=1LL*v[c[x]]*w[tax[c[x]]--];
  83. opt[x]^=1;
  84. }
  85. void update_Time(int i){
  86. int x=O[i].x,a=O[i].v1,b=O[i].v2;
  87. if (c[x]!=a)
  88. swap(a,b);
  89. if (opt[x])
  90. ans-=1LL*v[c[x]]*w[tax[c[x]]--];
  91. c[x]=b;
  92. if (opt[x])
  93. ans+=1LL*v[c[x]]*w[++tax[c[x]]];
  94. }
  95. void solve(){
  96. sort(Q+1,Q+Qcnt+1,cmp);
  97. O[0].id=0,O[Ocnt+1].id=q+1;
  98. memset(tax,0,sizeof tax);
  99. memset(opt,0,sizeof opt);
  100. int L=1,R=0,t=0;
  101. for (int i=1;i<=Qcnt;i++){
  102. while (L<Q[i].L)
  103. update(L++);
  104. while (L>Q[i].L)
  105. update(--L);
  106. while (R<Q[i].R)
  107. update(++R);
  108. while (R>Q[i].R)
  109. update(R--);
  110. while (O[t+1].id<Q[i].id)
  111. update_Time(++t);
  112. while (O[t].id>Q[i].id)
  113. update_Time(t--);
  114. Q[i].ans=ans+1LL*v[c[Q[i].LCA]]*w[tax[c[Q[i].LCA]]+1];
  115. }
  116. sort(Q+1,Q+Qcnt+1,cmpid);
  117. }
  118. int main(){
  119. n=read(),m=read(),q=read();
  120. for (int i=1;i<=m;i++)
  121. v[i]=read();
  122. for (int i=1;i<=n;i++)
  123. w[i]=read();
  124. g.clear();
  125. for (int i=1,a,b;i<n;i++){
  126. a=read(),b=read();
  127. g.add(a,b);
  128. g.add(b,a);
  129. }
  130. for (int i=1;i<=n;i++)
  131. dc[i]=c[i]=read();
  132. Time=0;
  133. dfs(1,0,0);
  134. for (int i=1;i<=n*2;i++)
  135. bID[i]=(i-1)/pow(n,0.666);
  136. Qcnt=Ocnt=0;
  137. for (int i=1;i<=q;i++){
  138. int opt=read(),x=read(),y=read();
  139. if (!opt){
  140. O[++Ocnt]=Operation(x,dc[x],y,i);
  141. dc[x]=y;
  142. }
  143. else {
  144. if (in[x]>in[y])
  145. swap(x,y);
  146. int lca=LCA(x,y);
  147. if (x==lca)
  148. Q[++Qcnt]=Query(in[x],in[y],i,0);
  149. else
  150. Q[++Qcnt]=Query(out[x],in[y],i,lca);
  151. }
  152. }
  153. solve();
  154. for (int i=1;i<=Qcnt;i++)
  155. printf("%lld\n",Q[i].ans);
  156. return 0;
  157. }

  

BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队的更多相关文章

  1. [BZOJ3052][UOJ#58][WC2013]糖果公园

    [BZOJ3052][UOJ#58][WC2013]糖果公园 试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来 ...

  2. 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法

    [题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...

  3. BZOJ3052 & UOJ58:[WC2013]糖果公园——题解

    http://uoj.ac/problem/58 http://www.lydsy.com/JudgeOnline/problem.php?id=3052 输入格式 输出格式 input 4 3 5 ...

  4. 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队

    [BZOJ3052][wc2013]糖果公园 Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 ...

  5. bzoj 3052: [wc2013]糖果公园 带修改莫队

    3052: [wc2013]糖果公园 Time Limit: 250 Sec  Memory Limit: 512 MBSubmit: 506  Solved: 189[Submit][Status] ...

  6. 【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)

    题目描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 \(n\) 个游 ...

  7. 洛谷 P4074 [WC2013]糖果公园 解题报告

    P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...

  8. AC日记——[WC2013]糖果公园 cogs 1817

    [WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...

  9. COGS1817. [WC2013]糖果公园

    1817. [WC2013]糖果公园 ★★★☆   输入文件:park.in   输出文件:park.out   简单对比时间限制:8 s   内存限制:512 MB [题目描述] Candyland ...

随机推荐

  1. Ex 2_3 求递推式的通项公式..._第三次作业

  2. Sql 08数据库还原数据库时一直提示数据库被占用

    直接试试这个sql语句吧 ALTER DATABASE [datebase] SET OFFLINE WITH ROLLBACK IMMEDIATE ALTER database [datebase] ...

  3. Cropper.js使用笔记

    官网:https://fengyuanchen.github.io/cropperjs/ github:https://github.com/fengyuanchen/cropperjs 由于文档不好 ...

  4. 在Winform开发框架中实现对数据库的加密支持(转)

    在很多情况下,我们需要对数据库进行加密,特别是Access数据库.Sqlite数据库,这些直接部署在客户端的数据,因为数据也是客户的资产,数据库总是存在很多相关的秘密或者重要的业务数据,所以一般来说, ...

  5. Java 开源博客 Solo 2.5.0 发布

    Java 开源博客 Solo 2.5.0 发布 Solo 是一款一个命令就能搭建好的 Java 开源博客系统,如果你想开个独立博客,请一定不要错过! 2.5.0 版本主要支持了 Markdown/JS ...

  6. 动态获取后台传过来的值作为select选项

    问题描述:点击左侧菜单项,进入对应的具体页面a.html,页面上方有个select框,点击框后,会浮现选择项. 解决思路:对左侧菜单项添加一个onclick事件,进入后台做具体的查询,将查询到的lis ...

  7. VGG-Net

    论文下载 源码GitHub 目的 这篇文章是以比赛为目的——解决ImageNet中的1000类图像分类和定位问题.在此过程中,作者做了六组实验,对应6个不同的网络模型,这六个网络深度逐渐递增的同时,也 ...

  8. kali linux宿主机和虚拟机互访实现方案

    1.攻防模拟中,将DVWA安装到自己的宿主机中,在kali Linux中通过sqlmap和其他工具启动嗅探攻击,需要配置网络.虚拟机采用桥接方式,并复制Mac地址状况. 2.查看各自系统下的IP地址. ...

  9. 利用vue-cli创建新项目

    1.安装vue-cli npm i vue-cli --gd 2.初始化一个项目 vue init webpack test //test 是个项目名称并且配置相应的配置,(测试部份的可以选择no) ...

  10. du命令

    选项 例1:显示单个文件的大小(默认单位K) [root@zabbix alertscripts]# du -h sendim.py 4.0k sendim.py 例2:显示某个目录的总大小 例3:输 ...