JZOJ 5460. 士兵训练

题目

\(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\)

#include<cstdio>#include<iostream>#define ls (p << 1)#define rs (ls | 1)using namespace std;const int N = 2e5   5, INF = 2e9;int n, q, dfc, tot, h[N], fa[N], dfn[N], rev[N], siz[N], B[N], L[N];struct edge{int to, nxt;}e[N];struct node{int mx, cmx, cnt, cc, mxl, cmxl;}seg[N << 2];inline int add(int x, int y){e[  tot] = edge{y, h[x]}, h[x] = tot;}int st[N], top; void dfs(int x){st[  top] = 1, dfn[x] =   dfc, rev[dfc] = x, siz[x] = 1;while (top){int x = st[top], v = e[h[x]].to;int bz = 0;if (h[x]){st[  top] = v, dfn[v] =   dfc, rev[dfc] = v, siz[v] = 1, h[x] = e[h[x]].nxt, bz = 1;}if (!bz) top--, siz[fa[x]]  = siz[x];}}inline node get1(node x, node y){if (x.mx == y.mx){if (x.cmx == y.cmx) return node{x.mx, x.cmx, x.cnt   y.cnt, max(x.cc, y.cc)};else if (x.cmx > y.cmx) return node{x.mx, x.cmx, x.cnt   y.cnt, max(x.cc, y.cmx)};return node{x.mx, y.cmx, x.cnt   y.cnt, max(x.cmx, y.cc)};}else if (x.mx > y.mx) {if (x.cmx == y.mx) return node{x.mx, x.cmx, x.cnt, max(x.cc, y.cmx)};else if (x.cmx > y.mx) return node{x.mx, x.cmx, x.cnt, max(x.cc, y.mx)};return node{x.mx, y.mx, x.cnt, max(x.cmx, y.cmx)};}else{if (x.mx == y.cmx) return node{y.mx, x.mx, y.cnt, max(x.cmx, y.cc)};else if (x.mx > y.cmx) return node{y.mx, x.mx, y.cnt, max(x.cmx, y.cmx)};return node{y.mx, y.cmx, y.cnt, max(x.mx, y.cc)};}}inline node get2(node x, node y){if (x.mxl == y.mxl) return node{0, 0, 0, 0, x.mxl, max(x.cmxl, y.cmxl)};else if (x.mxl > y.mxl) return node{0, 0, 0, 0, x.mxl, max(x.cmxl, y.mxl)};return node{0, 0, 0, 0, y.mxl, max(x.mxl, y.cmxl)};}void build(int l, int r, int p){if (l == r){seg[p].mx = B[rev[l]], seg[p].mxl = L[rev[l]], seg[p].cnt = 1;seg[p].cmx = seg[p].cmxl = seg[p].cc = -INF;return;}int mid = (l   r) >> 1;build(l, mid, ls), build(mid   1, r, rs);seg[p] = get1(seg[ls], seg[rs]);node K = get2(seg[ls], seg[rs]);seg[p].mxl = K.mxl, seg[p].cmxl = K.cmxl;}node query1(int l, int r, int p, int x, int y){if (x > y) return node{-INF, -INF, 0, -INF, -INF, -INF};if (x <= l && r <= y) return seg[p];int mid = (l   r) >> 1;node K1, K2;K1 = K2 = node{-INF, -INF, 0, -INF, -INF, -INF};if (x <= mid) K1 = query1(l, mid, ls, x, y);if (y > mid) K2 = query1(mid   1, r, rs, x, y);return get1(K1, K2);}node query2(int l, int r, int p, int x, int y){if (x > y) return node{-INF, -INF, 0, -INF, -INF, -INF};if (x <= l && r <= y) return seg[p];int mid = (l   r) >> 1;node K1, K2, K;K1 = K2 = node{-INF, -INF, 0, -INF, -INF, -INF};if (x <= mid) K1 = query2(l, mid, ls, x, y);if (y > mid) K2 = query2(mid   1, r, rs, x, y);return get2(K1, K2);}int main(){freopen("soldier.in", "r", stdin);freopen("soldier.out", "w", stdout);scanf("%d%d", &n, &q);for(int i = 1; i < n; i  ) scanf("%d", &fa[i   1]), add(fa[i   1], i   1);for(int i = 1; i <= n; i  ) scanf("%d%d", &B[i], &L[i]);dfs(1), build(1, n, 1);for(; q; --q){int s, ans = 0; node K1, K2, K, Kl;scanf("%d", &s);K = query1(1, n, 1, dfn[s], dfn[s]   siz[s] - 1);if (siz[s] == 1){printf("0\n"); continue;}K1 = query2(1, n, 1, 1, dfn[s] - 1), K2 = query2(1, n, 1, dfn[s]   siz[s], n), Kl = get2(K1, K2);if ((K.cnt > 1 && K.mx   Kl.mxl > K.mx) || (K.cmx   Kl.mxl > K.mx)) ans = K.mx;else{ans = K.cmx   Kl.mxl;if (ans == K.mx) ans = max(K.cmx   Kl.cmxl, K.cc   Kl.mxl);if (ans < 0) ans = K.cmx;}printf("%d\n", ans);}}

来源:https://www.icode9.com/content-4-875801.html

(0)

相关推荐