题目

\(1\le n,q \le 2\cdot {10}^5,0\le b_i,l_i \le {10}^9,b_i \ge 1,1 \le S_i \le n\)

\(Solution\)

这题很好想

总之要维护子树内 \(b\) 值的严格最大(包括数量),次大,次次大,\(l\) 值的严格最大,次大

然后分类讨论,注意相等的情况,接下来就是码的事了

注意要打人工栈!!

\(Code\)

  1. #include<cstdio>
  2. #include<iostream>
  3. #define ls (p << 1)
  4. #define rs (ls | 1)
  5. using namespace std;
  6. const int N = 2e5 + 5, INF = 2e9;
  7. int n, q, dfc, tot, h[N], fa[N], dfn[N], rev[N], siz[N], B[N], L[N];
  8. struct edge{int to, nxt;}e[N];
  9. struct node{int mx, cmx, cnt, cc, mxl, cmxl;}seg[N << 2];
  10. inline int add(int x, int y){e[++tot] = edge{y, h[x]}, h[x] = tot;}
  11. int st[N], top;
  12. void dfs(int x)
  13. {
  14. st[++top] = 1, dfn[x] = ++dfc, rev[dfc] = x, siz[x] = 1;
  15. while (top)
  16. {
  17. int x = st[top], v = e[h[x]].to;
  18. int bz = 0;
  19. if (h[x]){st[++top] = v, dfn[v] = ++dfc, rev[dfc] = v, siz[v] = 1, h[x] = e[h[x]].nxt, bz = 1;}
  20. if (!bz) top--, siz[fa[x]] += siz[x];
  21. }
  22. }
  23. inline node get1(node x, node y)
  24. {
  25. if (x.mx == y.mx)
  26. {
  27. if (x.cmx == y.cmx) return node{x.mx, x.cmx, x.cnt + y.cnt, max(x.cc, y.cc)};
  28. else if (x.cmx > y.cmx) return node{x.mx, x.cmx, x.cnt + y.cnt, max(x.cc, y.cmx)};
  29. return node{x.mx, y.cmx, x.cnt + y.cnt, max(x.cmx, y.cc)};
  30. }
  31. else if (x.mx > y.mx)
  32. {
  33. if (x.cmx == y.mx) return node{x.mx, x.cmx, x.cnt, max(x.cc, y.cmx)};
  34. else if (x.cmx > y.mx) return node{x.mx, x.cmx, x.cnt, max(x.cc, y.mx)};
  35. return node{x.mx, y.mx, x.cnt, max(x.cmx, y.cmx)};
  36. }
  37. else{
  38. if (x.mx == y.cmx) return node{y.mx, x.mx, y.cnt, max(x.cmx, y.cc)};
  39. else if (x.mx > y.cmx) return node{y.mx, x.mx, y.cnt, max(x.cmx, y.cmx)};
  40. return node{y.mx, y.cmx, y.cnt, max(x.mx, y.cc)};
  41. }
  42. }
  43. inline node get2(node x, node y)
  44. {
  45. if (x.mxl == y.mxl) return node{0, 0, 0, 0, x.mxl, max(x.cmxl, y.cmxl)};
  46. else if (x.mxl > y.mxl) return node{0, 0, 0, 0, x.mxl, max(x.cmxl, y.mxl)};
  47. return node{0, 0, 0, 0, y.mxl, max(x.mxl, y.cmxl)};
  48. }
  49. void build(int l, int r, int p)
  50. {
  51. if (l == r)
  52. {
  53. seg[p].mx = B[rev[l]], seg[p].mxl = L[rev[l]], seg[p].cnt = 1;
  54. seg[p].cmx = seg[p].cmxl = seg[p].cc = -INF;
  55. return;
  56. }
  57. int mid = (l + r) >> 1;
  58. build(l, mid, ls), build(mid + 1, r, rs);
  59. seg[p] = get1(seg[ls], seg[rs]);
  60. node K = get2(seg[ls], seg[rs]);
  61. seg[p].mxl = K.mxl, seg[p].cmxl = K.cmxl;
  62. }
  63. node query1(int l, int r, int p, int x, int y)
  64. {
  65. if (x > y) return node{-INF, -INF, 0, -INF, -INF, -INF};
  66. if (x <= l && r <= y) return seg[p];
  67. int mid = (l + r) >> 1;
  68. node K1, K2;
  69. K1 = K2 = node{-INF, -INF, 0, -INF, -INF, -INF};
  70. if (x <= mid) K1 = query1(l, mid, ls, x, y);
  71. if (y > mid) K2 = query1(mid + 1, r, rs, x, y);
  72. return get1(K1, K2);
  73. }
  74. node query2(int l, int r, int p, int x, int y)
  75. {
  76. if (x > y) return node{-INF, -INF, 0, -INF, -INF, -INF};
  77. if (x <= l && r <= y) return seg[p];
  78. int mid = (l + r) >> 1;
  79. node K1, K2, K;
  80. K1 = K2 = node{-INF, -INF, 0, -INF, -INF, -INF};
  81. if (x <= mid) K1 = query2(l, mid, ls, x, y);
  82. if (y > mid) K2 = query2(mid + 1, r, rs, x, y);
  83. return get2(K1, K2);
  84. }
  85. int main()
  86. {
  87. freopen("soldier.in", "r", stdin);
  88. freopen("soldier.out", "w", stdout);
  89. scanf("%d%d", &n, &q);
  90. for(int i = 1; i < n; i++) scanf("%d", &fa[i + 1]), add(fa[i + 1], i + 1);
  91. for(int i = 1; i <= n; i++) scanf("%d%d", &B[i], &L[i]);
  92. dfs(1), build(1, n, 1);
  93. for(; q; --q)
  94. {
  95. int s, ans = 0; node K1, K2, K, Kl;
  96. scanf("%d", &s);
  97. K = query1(1, n, 1, dfn[s], dfn[s] + siz[s] - 1);
  98. if (siz[s] == 1){printf("0\n"); continue;}
  99. K1 = query2(1, n, 1, 1, dfn[s] - 1), K2 = query2(1, n, 1, dfn[s] + siz[s], n), Kl = get2(K1, K2);
  100. if ((K.cnt > 1 && K.mx + Kl.mxl > K.mx) || (K.cmx + Kl.mxl > K.mx)) ans = K.mx;
  101. else{
  102. ans = K.cmx + Kl.mxl;
  103. if (ans == K.mx) ans = max(K.cmx + Kl.cmxl, K.cc + Kl.mxl);
  104. if (ans < 0) ans = K.cmx;
  105. }
  106. printf("%d\n", ans);
  107. }
  108. }

JZOJ 5460. 士兵训练的更多相关文章

  1. 【题解】士兵训练-C++

    题目DescriptionN个士兵排成一队进行军事训练,每个士兵的等级用1…K范围内的数来表示,长官每隔1小时就随便说出M个等级a1,a2…am(1≤ai≤K,M个等级中允许有重复),如果这M个等级组 ...

  2. python操作三大主流数据库(13)python操作redis之新闻项目实战①新闻数据的导入

    1.新闻处理页面redis_news.py #coding:utf-8 import math import redis class RedisNews(object): def __init__(s ...

  3. python操作三大主流数据库(10)python操作mongodb数据库④mongodb新闻项目实战

    python操作mongodb数据库④mongodb新闻项目实战 参考文档:http://flask-mongoengine.readthedocs.io/en/latest/ 目录: [root@n ...

  4. 【BZOJ2874】训练士兵(主席树)

    题意:有一个N*M的矩阵,给出一些形如(x1,y1,x2,y2,s)的操作,代表(x1,y1)到(x2,y2)都被加上了s这个数 现在有一些强制在线的询问,询问(x1,y1)到(x2,y2)的和 对于 ...

  5. BZOJ2874 : 训练士兵

    设$a[i][j]$表示$(i,j)$右下角要增加多少 $aj[i][j]=a[i][j]\times j$ $ai[i][j]=a[i][j]\times i$ $aij[i][j]=a[i][j] ...

  6. 2019.01.22 bzoj2874: 训练士兵(主席树)

    传送门 题意简述:给出一个n∗mn*mn∗m的矩阵n,m≤1e8n,m\le1e8n,m≤1e8,支持矩形加,矩形求和,强制在线. 思路:第一眼二维动态开点线段树,上网去搜有没有这种做法发现会被卡时空 ...

  7. fzyzojP3618 -- [校内训练-互测20180412]士兵的游戏

    二分图匈牙利也可以 判断必须点就看能不能通过偶数长度的增广路翻过去 代码: (最后一个点4s多才行,,,卡不过算了) 开始边数写少了RE,应该是4*N*N M-R随手开了一堆int?都要是long l ...

  8. BZOJ2874 训练士兵 主席树

    [啊 首先 这是道权限题,然后本人显然是没有权限的  23咳3] 最近数据结构做的越来越少..然后 就跟上次一样 ,一做就是三四种不同写法. 等价的题面: 最近GY大神在sc2的天梯中被神族虐得很惨, ...

  9. 暑假集训(1)第一弹 -----士兵队列训练问题(Hdu1276)

    Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报 ...

  10. hdoj 1276 士兵队列训练问题【模拟】

    士兵队列训练问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. 关于python3格式化字符输出的问题

    前言 今天简答写了一个爬虫,利用 % 格式化输出总是有问题 第一种写法: url = 'https://yysygw.res.netease.com/pc/gw/20190826151318/data ...

  2. 3.4:使用Weka实现KNN分类的算法示例

    〇.概述 1.使用Weka平台,并在该平台使用数据导入.可视化等基本操作: 2.对KNN算法的不同k值进行比较,对比结果得出结论. 一.打开Weka3.8并导入数据 二.导入数据 三.KNN算法分类操 ...

  3. Go | 闭包的使用

    闭包基本介绍 闭包就是 一个函数 和其相关的 引用环境 组合的一个整体 好处: 保存引用的变量,下次继续使用,不会销毁 下面通过闭包的方式,写一个数字累加器,体验一下闭包的妙处 闭包实现数字累加 pa ...

  4. 【机器学习】李宏毅——Anomaly Detection(异常检测)

    异常检测概述 首先要明确一下什么是异常检测任务.对于异常检测任务来说,我们希望能够通过现有的样本来训练一个架构,它能够根据输入与现有样本之间是否足够相似,来告诉我们这个输入是否是异常的,例如下图: 那 ...

  5. get请求拼接数组转字符串

    get请求拼接数组转换成字符串

  6. 2022CSP-J线上游记

    写在前面 安徽CSP取消了-- 去年CSP考炸的我本来想今年一雪前耻(bushi),结果-- T1 第一题大毒瘤! 首先观察数据可以分类如下两种情况: \(a = 1\) 直接输出\(1\),retu ...

  7. 学习ASP.NET Core Blazor编程系列二十一——数据刷新

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  8. for循环 rang方法

    今日内容 while循环补充说明 1.死循环 真正的死循环是一旦执行 cpu的功耗急剧上升 直到系统采取紧急措施 2.嵌套及全局标志位 强调: 一个break只能结束他所在那一层的循环 如果想一次性结 ...

  9. ionic+vue+capacitor系列笔记--手机从安卓10升级到安卓11以后,之前的代码不管用了,无法跳转其他应用

    之前手机是安卓10版本,没什么问题,升级以后,手机出现了一些异常,发现原来代码里写的跳转功能,无法使用了哦~~脑壳痛 解决方案 本项目:build.gradle targetSdkVersion 30 ...

  10. StringBuilder的原理-append方法

    StringBuilder的原理 append方法 根据StringBuilder的API文档,常用构造方法有2个:public stringBuilder():构造一个空的StringBuilder ...