【题目链接】

点击打开链接

【算法】

树链剖分

每个宗教建一棵线段树,注意数据量大,要动态开点

【代码】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define MAXLOG 18
  4. const int MAXN = 1e5 + ;
  5. const int MAXS = 1e7 + ;
  6.  
  7. int i,n,q,x,y,t,Lca,SZ,timer;
  8. int w[MAXN],c[MAXN],son[MAXN],dfn[MAXN],top[MAXN],size[MAXN],anc[MAXN][MAXLOG],
  9. dep[MAXN],fa[MAXN],lc[MAXS],rc[MAXS],sum[MAXS],Max[MAXS],root[MAXN];
  10. vector<int> e[MAXN];
  11. char opt[];
  12.  
  13. inline void dfs1(int x)
  14. {
  15. int i,y;
  16. anc[x][] = fa[x];
  17. for (i = ; i < MAXLOG; i++)
  18. {
  19. if (dep[x] < ( << i)) break;
  20. anc[x][i] = anc[anc[x][i-]][i-];
  21. }
  22. size[x] = ;
  23. for (i = ; i < e[x].size(); i++)
  24. {
  25. y = e[x][i];
  26. if (fa[x] != y)
  27. {
  28. dep[y] = dep[x] + ;
  29. fa[y] = x;
  30. dfs1(y);
  31. size[x] += size[y];
  32. if (size[y] > size[son[x]]) son[x] = y;
  33. }
  34. }
  35. }
  36. inline void dfs2(int x,int tp)
  37. {
  38. int i,y;
  39. dfn[x] = ++timer;
  40. top[x] = tp;
  41. if (son[x]) dfs2(son[x],tp);
  42. for (i = ; i < e[x].size(); i++)
  43. {
  44. y = e[x][i];
  45. if (fa[x] != y && son[x] != y) dfs2(y,y);
  46. }
  47. }
  48. inline int lca(int x,int y)
  49. {
  50. int i,t;
  51. if (dep[x] > dep[y]) swap(x,y);
  52. t = dep[y] - dep[x];
  53. for (i = ; i < MAXLOG; i++)
  54. {
  55. if (t & ( << i))
  56. y = anc[y][i];
  57. }
  58. if (x == y) return x;
  59. for (i = MAXLOG - ; i >= ; i--)
  60. {
  61. if (anc[x][i] != anc[y][i])
  62. {
  63. x = anc[x][i];
  64. y = anc[y][i];
  65. }
  66. }
  67. return fa[x];
  68. }
  69. inline void push_up(int root)
  70. {
  71. Max[root] = max(Max[lc[root]],Max[rc[root]]);
  72. sum[root] = sum[lc[root]] + sum[rc[root]];
  73. }
  74. inline void modify(int &root,int l,int r,int x,int val)
  75. {
  76. int mid;
  77. if (!root) root = ++SZ;
  78. if (l == r)
  79. {
  80. Max[root] = sum[root] = val;
  81. return;
  82. }
  83. mid = (l + r) >> ;
  84. if (mid >= x) modify(lc[root],l,mid,x,val);
  85. else modify(rc[root],mid+,r,x,val);
  86. push_up(root);
  87. }
  88. inline int query_max(int root,int l,int r,int ql,int qr)
  89. {
  90. int mid;
  91. if (!root) return ;
  92. if (l == ql && r == qr) return Max[root];
  93. mid = (l + r) >> ;
  94. if (mid >= qr) return query_max(lc[root],l,mid,ql,qr);
  95. else if (mid + <= ql) return query_max(rc[root],mid+,r,ql,qr);
  96. else return max(query_max(lc[root],l,mid,ql,mid),query_max(rc[root],mid+,r,mid+,qr));
  97. }
  98. inline int query_sum(int root,int l,int r,int ql,int qr)
  99. {
  100. int mid;
  101. if (!root) return ;
  102. if (l == ql && r == qr) return sum[root];
  103. mid = (l + r) >> ;
  104. if (mid >= qr) return query_sum(lc[root],l,mid,ql,qr);
  105. else if (mid + <= ql) return query_sum(rc[root],mid+,r,ql,qr);
  106. else return query_sum(lc[root],l,mid,ql,mid) + query_sum(rc[root],mid+,r,mid+,qr);
  107. }
  108.  
  109. inline int solve1(int c,int x,int y)
  110. {
  111. int ans = ,
  112. tx = top[x],ty = top[y];
  113. while (tx != ty)
  114. {
  115. ans = max(ans,query_max(root[c],,n,dfn[tx],dfn[x]));
  116. x = fa[tx]; tx = top[x];
  117. }
  118. ans = max(ans,query_max(root[c],,n,dfn[y],dfn[x]));
  119. return ans;
  120. }
  121. inline int solve2(int c,int x,int y)
  122. {
  123. int ans = ,
  124. tx = top[x],ty = top[y];
  125. while (tx != ty)
  126. {
  127. ans += query_sum(root[c],,n,dfn[tx],dfn[x]);
  128. x = fa[tx]; tx = top[x];
  129. }
  130. ans += query_sum(root[c],,n,dfn[y],dfn[x]);
  131. return ans;
  132. }
  133.  
  134. int main()
  135. {
  136.  
  137. scanf("%d%d",&n,&q);
  138. for (i = ; i <= n; i++) scanf("%d%d",&w[i],&c[i]);
  139. for (i = ; i < n; i++)
  140. {
  141. scanf("%d%d",&x,&y);
  142. e[x].push_back(y);
  143. e[y].push_back(x);
  144. }
  145. dfs1();
  146. dfs2(,);
  147. for (i = ; i <= n; i++) modify(root[c[i]],,n,dfn[i],w[i]);
  148. while (q--)
  149. {
  150. scanf("%s",&opt);
  151. if (strcmp(opt,"CC") == )
  152. {
  153. scanf("%d%d",&x,&y);
  154. modify(root[c[x]],,n,dfn[x],);
  155. c[x] = y;
  156. modify(root[c[x]],,n,dfn[x],w[x]);
  157. }
  158. if (strcmp(opt,"CW") == )
  159. {
  160. scanf("%d%d",&x,&y);
  161. modify(root[c[x]],,n,dfn[x],y);
  162. w[x] = y;
  163. }
  164. if (strcmp(opt,"QS") == )
  165. {
  166. scanf("%d%d",&x,&y);
  167. Lca = lca(x,y);
  168. t = solve2(c[x],x,Lca) + solve2(c[x],y,Lca);
  169. if (c[Lca] == c[x]) t -= w[Lca];
  170. printf("%d\n",t);
  171. }
  172. if (strcmp(opt,"QM") == )
  173. {
  174. scanf("%d%d",&x,&y);
  175. Lca = lca(x,y);
  176. printf("%d\n",max(solve1(c[x],x,Lca),solve1(c[x],y,Lca)));
  177. }
  178. }
  179.  
  180. return ;
  181.  
  182. }

【SDOI 2014】 旅行的更多相关文章

  1. 【BZOJ 3531】【SDOI 2014】旅行

    因为有$10^5$个宗教,需要开$10^5$个线段树. 平时开的线段树是“满”二叉树,但在这个题中代表一个宗教的线段树管辖的区间有很多点都不属于这个宗教,也就不用“把枝叶伸到这个点上”,所以这样用类似 ...

  2. 【BZOJ 3529】【SDOI 2014】数表

    看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...

  3. [BZOJ 3530][Sdoi 2014]数数

    阿拉~好像最近总是做到 AC 自动机的题目呢喵~ 题目的算法似乎马上就能猜到的样子…… AC 自动机 + 数位 dp 先暴力转移出 f[i][j] :表示从 AC 自动机上第 j 号节点走 i 步且不 ...

  4. BZOJ 3533 sdoi 2014 向量集

    设(x,y)为Q的查询点,分类讨论如下:1.y>0:  最大化a*x+b*y,维护一个上凸壳三分即可 2.y<0:最大化a*x+b*y  维护一个下凸壳三分即可 我们考虑对时间建出一棵线段 ...

  5. [SDOI 2014]数表

    Description 有一张N×m的数表,其第i行第j列(1 < =i < =N,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...

  6. 解题:SDOI 2014 重建

    题面 做这个这个题需要稍微深入理解一点矩阵树定理:套矩阵树定理得到的东西是有意义的,它是“所有生成树边权乘积之和”(因为度数矩阵是点的边权和,邻接矩阵是边权),即$\sum_{t}\prod_{e∈t ...

  7. 解题:SDOI 2014 数表

    题面 为了好写式子,先不管$a$的限制 设$facs$为因子和,那么有 $ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^mfacs(gcd(i,j))$ 再设$f( ...

  8. 【BZOJ 3530】【SDOI 2014】数数

    http://www.lydsy.com/JudgeOnline/problem.php?id=3530 上午gty的测试题,爆0了qwq 类似文本生成器那道题,把AC自动机的转移建出来,准确地说建出 ...

  9. 「BZOJ 3529」「SDOI 2014」数表「莫比乌斯反演」

    题意 有一张 \(n\times m\) 的数表,其第\(i\)行第\(j\)列的数值为能同时整除\(i\)和\(j\)的所有自然数之和. \(T\)组数据,询问对于给定的 \(n,m,a\) , 计 ...

随机推荐

  1. SeLion数据驱动中遇到的问题,以及解决方案

    问题描述: 使用selion框架数据驱动时,总是test ignored. 解决方案: 把这个dataprovider方法拿出来做单元测试.有详细报错. 问题1:使用wps保存,poi包只能解析xls ...

  2. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

  3. Go --- 设计模式(工厂模式)

    简易工厂主要是用来解决对象“创建”的问题.以下的例子取自<大话设计模式>中第一章,实现一个可扩展的“计算器”.当增加新的功能时,并不需改动原来已经实现的算法.由于是简易工厂,所以我们还是需 ...

  4. 系统优化(一)Maven打包同一个jar有不同的:版本号+时间戳(解决思路)

    解决:maven仓库的ear里面有非常多个同样的jar(仅仅是包括不同的:版本号+时间戳) 问题描写叙述: 发现ear里面有非常多个同样的jar,仅仅是包括不同的:版本号+时间戳,例如以下图所看到的: ...

  5. 将oracle10g 升级至10.2.0.4

    http://blog.csdn.net/launch_225/article/details/7221489 一.单实例环境,全时长一个半钟多. 详细图文说明到这下载 1.停止所有oracle相关进 ...

  6. OCR简介及使用

    OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方法将形状翻译 ...

  7. iOS远程推送原理

    远程推送 就是从远程server推送消息给client的通知.当然须要联网. 远程推送服务APNs (Apple Push NotificationServices) 为什么须要远程推送通知? 传统获 ...

  8. 【安卓笔记】抽屉式布局----DrawerLayout

    效果例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hkamo=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  9. Linux 编译安装Boost

    linux平台下要编译安装除gcc和gcc-c++之外,还需要两个开发库:bzip2-devel 和python-devel,因此在安装前应该先保证这两个库已经安装: #yum install gcc ...

  10. js实现的美女瀑布流效果代码

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...