QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#227615#7563. Fun on Treeucup-team2307WA 0ms3624kbC++145.2kb2023-10-27 19:48:072023-10-27 19:48:07

Judging History

你现在查看的是最新测评结果

  • [2023-10-27 19:48:07]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3624kb
  • [2023-10-27 19:48:07]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) begin(x), end(x)
const ll inf = 1ll<<60;
struct Node {
    array<ll, 2> val = {-inf, -1};
    ll lazy = 0;
};
struct Tree {
    int n;
    vector<Node> tree;
    Tree(int N) : n(N), tree(4 * n + 4) {}
    void apply(int v, ll x, int len) {
        tree[v].val[0] += x;
        tree[v].lazy += x;
    }
    void push(int v, int len) {
        apply(2*v, tree[v].lazy, (len + 1) / 2);
        apply(2*v+1, tree[v].lazy, len / 2);
        tree[v].lazy = 0;
    }
    void update(int v, int l, int r, int ql, int qr, ll x) {
        if(qr < l || r < ql) return;
        if(ql <= l && r <= qr) {
            apply(v, x, r - l + 1);
            return;
        }
        push(v, r - l + 1);
        int m = (l + r) / 2;
        update(2 * v, l, m, ql, qr, x);
        update(2 * v + 1, m + 1, r, ql, qr, x);
        tree[v].val = max(tree[2*v].val, tree[2*v+1].val);
    }
    void update(int v, int l, int r, int qp, array<ll, 2> x) {
        if(qp < l || r < qp) return;
        if(l == r) {
            tree[v].val = x;
            return;
        }
        push(v, r - l + 1);
        int m = (l + r) / 2;
        update(2 * v, l, m, qp, x);
        update(2 * v + 1, m + 1, r, qp, x);
        tree[v].val = max(tree[2*v].val, tree[2*v+1].val);
    }
    array<ll, 2> query(int v, int l, int r, int ql, int qr) {
        if(qr < l || r < ql) return {-inf, -1};
        if(ql <= l && r <= qr) {
            return tree[v].val;
        }
        push(v, r - l + 1);
        int m = (l + r) / 2;
        return max(query(2 * v, l, m, ql, qr), query(2 * v + 1, m + 1, r, ql, qr));
    }
    array<ll, 2> query(int l, int r) { return query(1, 0, n - 1, l, r); }
    void update(int l, int r, ll x) { update(1, 0, n - 1, l, r, x); }
    void assign(int p, array<ll, 2> x) { update(1, 0, n - 1, p, x); }
};

int main() {
    cin.tie(0)->sync_with_stdio(0);
    // Tree st(10);
    // for(int i = 0; i < 10; i++)
    //     cout << st.query(i, i) << " "; cout << endl;
    // st.update(3, 5, 1);
    // st.update(0, 3, 10);
    // cout << st.query(4, 9) << endl;
    int n, q;
    cin >> n >> q;
    vector<int> a(n);
    for(auto &i : a) cin >> i;

    vector<vector<array<int, 2>>> g(n);
    for(int p, w, i = 1; i < n; i++) {
        cin >> p >> w;
        g[--p].push_back({i, w});
    }

    vector<int> par(n), sz(n);
    vector<ll> h(n);
    auto sizes = [&](auto self, int v) -> void {
        sz[v] = 1;
        for(auto &P : g[v]) {
            auto [i, w] = P;
            par[i] = v;
            h[i] = h[v] + w;
            self(self, i);
            sz[v] += sz[i];
            if(sz[i] > sz[g[v][0][0]])
                swap(P, g[v][0]);
        }
    };
    sizes(sizes, 0);
    
    int timer = 0;
    vector<int> tin(n), tout(n), head(n);
    auto hld = [&](auto self, int v) -> void {
        tin[v] = timer++;
        for(auto [i, w] : g[v]) {
            head[i] = i == g[v][0][0] ? head[v] : i;
            self(self, i);
        }
        tout[v] = timer;
    };
    hld(hld, 0);

    Tree seg_da(n), seg_hld(n);
    for(int i = 0; i < n; i++) {
        seg_da.assign(tin[i], {h[i] - a[i], i});
    }

    auto all_but = [&](int v, int son) {
        if(son == -1) {
            return seg_da.query(tin[v], tout[v] - 1);
        } else {
            return max(seg_da.query(tin[v], tin[son] - 1),
                       seg_da.query(tout[son], tout[v] - 1));
        }
    };

    for(int i = 0; i < n; i++) {
        auto T = all_but(i, sz[i] == 1 ? -1 : g[i][0][0]);
        T[0] -= 2*h[i];
        seg_hld.assign(tin[i], T);
    }

    auto update = [&](int v, ll x) {//sulfur content increases by x in subtree of v
        seg_da.update(tin[v], tout[v] - 1, -x);
        seg_hld.update(tin[v], tout[v] - 1, -x);
        while(true) {
            v = head[v];
            if(!v) break;
            v = par[v];
            auto T = all_but(v, g[v][0][0]);
            T[0] -= 2*h[v];
            seg_hld.assign(tin[v], T);
        }
    };
    // for(int i = 0; i < n; i++)
    //     cout << seg_da.query(i, i) << " "; cout << endl;
    // cout << all_but(3, -1) - h[3] << endl;
    auto query = [&](int v) -> array<ll, 2> {
        array<ll, 2> ans = {-inf, -1};
        ll son = -1, base = h[v];
        while(true) {
            if(son == -1) {//son
                auto X = all_but(v, -1);
                X[0] -= base;
                ans = max(ans, X);
            } else {//light edge case
                auto X = all_but(v, son);
                X[0] += base - 2*h[v];
                ans = max(ans, X);
            }
            if(!v) break;
            if(v != head[v]) {//heavy edge case
                auto X = seg_hld.query(tin[head[v]], tin[v] - 1);
                X[0] += base;
                ans = max(ans, X);
            }
            son = head[v];
            v = par[head[v]];
        }
        return ans;
    };

    int x, y, v;
    while(q--) {
        cin >> x >> y >> v;
        --x, --y;
        update(y, v);
        auto A = query(x);
        cout << A[1]+1 << " " << A[0] << '\n';
    }
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3624kb

input:

6 6
1 1 4 5 1 4
1 5
2 0
3 2
4 1
5 6
3 2 -100000
1 2 100000
1 1 0
2 2 66
3 1 5
4 4 -3

output:

6 100005
6 10
6 10
1 4
1 -1
1 1

result:

ok 6 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3620kb

input:

5 6
-10 0 2 -4 8
1 7
1 1
2 2
2 -2
1 1 100
2 1 -100
1 1 0
4 3 10
2 5 3
5 2 2

output:

4 -87
1 17
4 13
1 19
1 17
1 15

result:

ok 6 lines

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 3556kb

input:

6 3
0 0 0 0 0 0
1 10
1 10
1 -100
4 10
4 11
1 1 0
4 1 0
1 4 1000

output:

3 10
6 11
3 10

result:

wrong answer 1st lines differ - expected: '2 10', found: '3 10'