CodeForces 1178G: The Awesomest Vertex

Topic portal: CF1178G .

Description meaning of the questions:

A \ (n-\) ( \ (. 1 \ n-Le \ Le 2 \ 10. 5 ^ \) Times ) have points rooted tree, the \ (I \) points with a \ (a_i \) and \ (B_i \) two properties, initially to ensure \ (| a_i |, | b_i | \ Le 5000 \) .

Definition \ (I \) ancestor node points (including itself) is set \ (R & lt (I) \) .

The first \ (V \) weights defined points as \ (\ displaystyle \ left | \ sum_ {w \ in R (v)} a_w \ right | \ times \ left | \ sum_ {w \ in R (v) B_W} \ right | \) .

Performing \ (Q \) ( \ (. 1 \ Le Q \ Le 10. 5 \) ^ ) operations, each operation of one of the following two actions:

  1. 给定\ (u, x \) ( \ (1 \ g \ k \) , \ (1 \ X \ 5000 \) ):将\ (a_u \)增加\ (x \) .

  2. Given \ (U \) ( \ (. 1 \ Le U \ n-Le \) ): Output \ (U \) of maximum weight subtree.

answer:

Definition \ (I \) nodes within the subtree points (including itself) as set \ (S (I) \) .

Notice \ (b_i \) always does not change, we might make \ (\ DisplayStyle \ beta_u = \ left | \ sum_ {v \ in R (U)} B_v \ right | \) , note that \ (\ beta_i \) is a non negative; then make \ (\ DisplayStyle \ to alpha_u = \ sum_ {V \ R & lt in (U)} a_v \) .

Consider simplify operation 2, i.e., the requirement is \ (\ DisplayStyle \ max_ {V \ S in (U)} \ {| \ alpha_v | \ Times \ beta_v \} \) .

Since \ (\ beta_i \) non-negative, is further simplified as \ (\ displaystyle \ max \ left \ {\ max_ {v \ in S (u)} \ {\ alpha_v \ beta_v \}, - \ min_ {v \ S in (U)} \ {\ alpha_v \ beta_v \} \ right \} \) .

Requires maintenance interval \ (\ alpha_i \ beta_i \) of the maximum and minimum, where \ (\ beta_i \) is fixed non-negative, to support the section \ (\ alpha_i \) plus a positive number.

This is a classic problem, consider the block, each block only supports global plus \ (k \ beta_i \) and queries the global minimum to maximum.

Maintenance and down into the convex hull, with decreasing slope when asked to cut the linear convex hull may be used directly monotonically queue maintenance, to reconstruct the non-convex hull vertical block modification.

Here is the code card to pay attention to achieve constantly, time complexity \ (\ mathcal {O} (n-\ log n-Q + \ n-sqrt {}) \) :

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>

typedef long long LL;
typedef double db;
const int MN = 200005;
const int MB = 1345;

inline void ckmax(LL &x, const LL &y) { x = x < y ? y : x; }
inline LL Abs(const LL &x) { return x < 0 ? -x : x; }

int N, Q, faz[MN], A[MN], B[MN];
std::vector<int> G[MN];
LL X[MN], Y[MN];
int ldf[MN], rdf[MN], dfc;
void DFS(int u) {
    int id = ldf[u] = ++dfc;
    X[id] = X[ldf[faz[u]]] + B[u];
    Y[id] = Y[ldf[faz[u]]] + A[u];
    for (auto v : G[u]) DFS(v);
    X[id] = Abs(X[id]);
    Y[id] *= X[id];
    rdf[u] = dfc;
}

int S, T, bel[MN], lb[MB], rb[MB], lenk[MB];
int _id[MN], *idk[MB];
int _que1[MN], *que1k[MB], ql1[MB], qr1[MB];
int _que2[MN], *que2k[MB], ql2[MB], qr2[MB];
int rk[MB], tag[MB];
LL ans[MB];

inline db Slope(const int &i, const int &j) {
    if (X[i] == X[j]) {
        if (Y[i] == Y[j]) return 0;
        else if (Y[i] < Y[j]) return 1e99;
        else return -1e99;
    }
    return (db)(Y[j] - Y[i]) / (X[j] - X[i]);
}

inline void Flush(const int &k) {
    if (!tag[k]) return ;
    int *que1 = que1k[k], *que2 = que2k[k];
    int &l1 = ql1[k], &r1 = qr1[k];
    int &l2 = ql2[k], &r2 = qr2[k];
    while (l1 < r1 && Slope(que1[l1], que1[l1 + 1]) > -rk[k]) ++l1;
    while (l2 < r2 && Slope(que2[r2 - 1], que2[r2]) > -rk[k]) --r2;
    int p1 = que1[l1], p2 = que2[r2];
    ans[k] = std::max(Y[p1] + rk[k] * X[p1], -Y[p2] - rk[k] * X[p2]);
    tag[k] = 0;
}

inline void ReBuild(const int &k) {
    int *id = idk[k], *que1 = que1k[k], *que2 = que2k[k];
    int &l1 = ql1[k], &r1 = qr1[k];
    int &l2 = ql2[k], &r2 = qr2[k];
    l1 = l2 = 1, r1 = r2 = 0;
    for (int I = 1; I <= lenk[k]; ++I) {
        int i = id[I];
        while (l1 < r1 && Slope(que1[r1 - 1], que1[r1]) < Slope(que1[r1], i)) --r1;
        while (l2 < r2 && Slope(que2[r2 - 1], que2[r2]) > Slope(que2[r2], i)) --r2;
        que1[++r1] = i, que2[++r2] = i;
    }
    tag[k] = 1, Flush(k);
}

int main() {
    scanf("%d%d", &N, &Q);
    for (int i = 2; i <= N; ++i)
        scanf("%d", &faz[i]),
        G[faz[i]].push_back(i);
    for (int i = 1; i <= N; ++i) scanf("%d", &A[i]);
    for (int i = 1; i <= N; ++i) scanf("%d", &B[i]);
    DFS(1);
    S = 150, T = (N - 1) / S + 1;
    for (int i = 1; i <= N; ++i) bel[i] = (i - 1) / S + 1;
    for (int i = 1; i <= N; ++i) _id[i] = i;
    for (int i = 1; i <= T; ++i) {
        lb[i] = (i - 1) * S + 1;
        rb[i] = std::min(i * S, N);
        lenk[i] = rb[i] - lb[i] + 1;
        idk[i] = _id + lb[i] - 1;
        que1k[i] = _que1 + lb[i] - 1;
        que2k[i] = _que2 + lb[i] - 1;
        auto cmp = [](int i, int j) { return X[i] < X[j]; };
        std::sort(idk[i] + 1, idk[i] + lenk[i] + 1, cmp);
        ReBuild(i);
    }
    while (Q--) {
        int op, u;
        scanf("%d%d", &op, &u);
        int l = ldf[u], r = rdf[u];
        int bl = bel[l], br = bel[r];
        if (op == 1) {
            int val;
            scanf("%d", &val);
            if (bl < br) {
                for (int i = l; i <= rb[bl]; ++i) Y[i] += val * X[i];
                for (int i = lb[br]; i <= r; ++i) Y[i] += val * X[i];
                ReBuild(bl), ReBuild(br);
                for (int k = bl + 1; k < br; ++k) rk[k] += val, tag[k] = 1;
            }
            else {
                for (int i = l; i <= r; ++i) Y[i] += val * X[i];
                ReBuild(bl);
            }
        }
        if (op == 2) {
            LL Ans = 0;
            if (bl < br) {
                for (int i = l; i <= rb[bl]; ++i) ckmax(Ans, Abs(Y[i] + rk[bl] * X[i]));
                for (int i = lb[br]; i <= r; ++i) ckmax(Ans, Abs(Y[i] + rk[br] * X[i]));
                for (int k = bl + 1; k < br; ++k) Flush(k), ckmax(Ans, ans[k]);
            }
            else for (int i = l; i <= r; ++i) ckmax(Ans, Abs(Y[i] + rk[bl] * X[i]));
            printf("%lld\n", Ans);
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/PinkRabbit/p/CF1178G.html