题目链接:http://codeforces.com/contest/832/problem/D

题意:给定一棵n个点的树,然后给你q个询问,每个询问为三元组(a,b,c),问你从这三个点中选取一个作为终点,一个作为Misha的起点,一个作为Grisha的起点。然后每天早上Misha从起点到终点所经过的点都是标记为1, 傍晚Grisha从起点到终点所经过的点中带有标记的点的数目最多是多少?

思路:对于每个询问,我们枚举终点(共3种情况),其余两个点作为一个作为M的起点一个作为G的起点,然后问题就是M的起点到终点这条路径的点赋值1,统计G的起点到终点这条路径的1的个数,然后3种情况取个最大值即可。 然后就是经典的树链剖分题目,树剖之后就是区间覆盖+区间查询问题了。 起初用的是线段树,然后终测TLE掉了(可能我写的线段树不够优美,被卡常了),后来换成树状数组来维护区间覆盖,区间查询就AC掉了。

  1. #define _CRT_SECURE_NO_DEPRECATE
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<string>
  7. #include<queue>
  8. #include<vector>
  9. #include<time.h>
  10. #include<cmath>
  11. using namespace std;
  12. typedef long long int LL;
  13. const int MAXN = 1e5 + ;
  14. const int INF = 0x3f3f3f3f;
  15. const int mod = 1e9 + ;
  16. int fa[MAXN],top[MAXN],deep[MAXN],num[MAXN],p[MAXN],fp[MAXN],son[MAXN];
  17. int pos,cp[MAXN],n,q;
  18. LL bit0[MAXN],bit1[MAXN];
  19. vector<int>edge[MAXN];
  20. void init(){
  21. pos = ;
  22. memset(bit0,,sizeof(bit0));
  23. memset(bit1,,sizeof(bit1));
  24. memset(son, -, sizeof(son));
  25. }
  26. void dfs1(int u, int pre, int d){
  27. deep[u] = d; fa[u] = pre; num[u] = ;
  28. for (int i = ; i < edge[u].size(); i++){
  29. int v = edge[u][i];
  30. if (v != pre){
  31. dfs1(v, u, d + );
  32. num[u] += num[v];
  33. if (son[u] == - || num[v] > num[son[u]]
  34. ){
  35. son[u] = v;
  36. }
  37. }
  38. }
  39. }
  40. void dfs2(int u, int sp){
  41. top[u] = sp; p[u] = pos++; fp[p[u]] = u;
  42. if (son[u] == -){
  43. return;
  44. }
  45. dfs2(son[u], sp);
  46. for (int i = ; i < edge[u].size(); i++){
  47. int v = edge[u][i];
  48. if (v != fa[u] && v != son[u]){
  49. dfs2(v, v);
  50. }
  51. }
  52. }
  53.  
  54. //BIT
  55. void Add(LL *b,int i,LL val){
  56. while (i<=n){
  57. b[i]+=val; i+=i&-i;
  58. }
  59. }
  60. LL Sum(LL *b,int i){
  61. LL s=;
  62. while (i>){
  63. s+=b[i]; i-=i&-i;
  64. }
  65. return s;
  66. }
  67. void Modify(int l,int r,int val){ //区间[l,r] + val
  68. //printf("M:%d %d %d\n",l,r,val);
  69. Add(bit0,l,-val*(l-));
  70. Add(bit1,l,val);
  71. Add(bit0,r+,val*r);
  72. Add(bit1,r+,-val);
  73. }
  74. int Query(int l,int r){ //区间[l,r] 1 的个数
  75. //printf("Q:%d %d\n",l,r);
  76. LL res=;
  77. res+=Sum(bit0,r)+1LL*Sum(bit1,r)*r;
  78. res-=Sum(bit0,l-)+1LL*Sum(bit1,l-)*(l-);
  79. return res;
  80. }
  81. void solveC(int u, int v,int val){ //修改链
  82. int f1 = top[u], f2 = top[v];
  83. while (f1!=f2){
  84. if (deep[f1] < deep[f2]){
  85. swap(f1, f2); swap(u, v);
  86. }
  87. Modify(p[f1], p[u], val);
  88. u = fa[f1];
  89. f1 = top[u];
  90. }
  91. if (deep[u] > deep[v]){
  92. swap(u, v);
  93. }
  94. Modify(p[u], p[v], val);
  95. }
  96. int solveQ(int u, int v){ //查询链
  97. int f1 = top[u], f2 = top[v];
  98. int tmp = ;
  99. while (f1 != f2){
  100. if (deep[f1] < deep[f2]){
  101. swap(f1, f2); swap(u, v);
  102. }
  103. tmp+=Query(p[f1], p[u]);
  104. u = fa[f1]; f1 = top[u];
  105. }
  106. if (deep[u] > deep[v]){
  107. swap(u, v);
  108. }
  109. tmp+=Query(p[u], p[v]);
  110. return tmp;
  111. }
  112. int solve(int s, int t, int f){
  113. solveC(s, f, );
  114. int tmp = solveQ(t, f);
  115. solveC(s, f, -);
  116. return tmp;
  117. }
  118. int main(){
  119. #ifdef kirito
  120. freopen("in.txt", "r", stdin);
  121. freopen("out.txt", "w", stdout);
  122. #endif
  123. while (~scanf("%d%d",&n,&q)){
  124. init();
  125. for (int i = ; i <= n; i++){
  126. edge[i].clear();
  127. }
  128. for (int i = ; i <= n; i++){
  129. scanf("%d", &cp[i]);
  130. edge[cp[i]].push_back(i);
  131. edge[i].push_back(cp[i]);
  132. }
  133. dfs1(, , );
  134. dfs2(, );
  135. for (int i = ; i <= q; i++){
  136. int a, b, c,res=;
  137. scanf("%d%d%d", &a, &b, &c);
  138. res = max(res, solve(a, b, c));
  139. res = max(res, solve(a, c, b));
  140. res = max(res, solve(b, c, a));
  141. printf("%d\n", res);
  142. }
  143. }
  144. return ;
  145. }

Codeforces Round #425 (Div. 2) - D的更多相关文章

  1. Codeforces Round #425 (Div. 2)C

    题目连接:http://codeforces.com/contest/832/problem/C C. Strange Radiation time limit per test 3 seconds ...

  2. Codeforces Round #425 (Div. 2)

    A 题意:给你n根棍子,两个人每次拿m根你,你先拿,如果该谁拿的时候棍子数<m,这人就输,对手就赢,问你第一个拿的人能赢吗 代码: #include<stdio.h>#define ...

  3. Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  4. Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论

    n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...

  5. Codeforces Round #425 (Div. 2) Problem B Petya and Exam (Codeforces 832B) - 暴力

    It's hard times now. Today Petya needs to score 100 points on Informatics exam. The tasks seem easy ...

  6. Codeforces Round #425 (Div. 2) Problem A Sasha and Sticks (Codeforces 832A)

    It's one more school day now. Sasha doesn't like classes and is always bored at them. So, each day h ...

  7. Codeforces Round #425 (Div. 2) B. Petya and Exam(字符串模拟 水)

    题目链接:http://codeforces.com/contest/832/problem/B B. Petya and Exam time limit per test 2 seconds mem ...

  8. Codeforces Round #425 (Div. 2))——A题&&B题&&D题

    A. Sasha and Sticks 题目链接:http://codeforces.com/contest/832/problem/A 题目意思:n个棍,双方每次取k个,取得多次数的人获胜,Sash ...

  9. Codeforces Round #425 (Div. 2) B - Petya and Exam

    地址:http://codeforces.com/contest/832/problem/B 题目: B. Petya and Exam time limit per test 2 seconds m ...

  10. Codeforces Round #425 (Div. 2) C - Strange Radiation

    地址:http://codeforces.com/contest/832/problem/C 题目: C. Strange Radiation time limit per test 3 second ...

随机推荐

  1. Android 输入法截取key优先于view

    为了验证编写了个例子 首先是输入法 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class RemoteKeyboard exte ...

  2. 20180912-Java实例02

    Java 实例 – 删除字符串中的一个字符 以下实例中我们通过字符串函数 substring() 函数来删除字符串中的一个字符,我们将功能封装在 removeCharAt 函数中. // Main.j ...

  3. Android操作系统中11种传感器的介绍【转】

    本文转载自:http://www.oschina.net/question/163910_28354 在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用. ...

  4. JSONPath解析json

    JSONPath - 用于JSON的XPath 用来解析多层嵌套的json数据;JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具. 考虑到接下来计划开发一个自动化测试平台,在 ...

  5. 【SD系列】SAP 退货冲账过账成本更新

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SD系列]SAP 退货冲账过账成本更新   前 ...

  6. Spring MVC配置文件

    都说开发Spring Web程序的配置文件很繁琐,所以就写了一篇配置博客, 首先是pom.xml文件 <project xmlns="http://maven.apache.org/P ...

  7. Node.js实战9:用EventEmitter触发和响应事件。

    Nodejs有一个重要的事件模块:EventEmitter. 它在Nodejs的内置及第三方模块中被大量使用,许多Nodejs项目的架构都是用它实现的. 可见,EventEmitter对于学习Node ...

  8. Win10不能远程其他远程计算机的解决办法

    Win10不能远程其他远程计算机的解决办法   转自: https://blog.csdn.net/qq_38197830/article/details/69488236 首先打开控制面板——> ...

  9. python字典使用总结

    作者:python技术人 博客:https://www.cnblogs.com/lpdeboke 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值 key=>value 对用冒号 ...

  10. MySql-8.0.16版本部分安装问题修正

    本帖参考网站<https://blog.csdn.net/lx318/article/details/82686925>的安装步骤,并对8.0.16版本的部分安装问题进行修正 在MySQL ...