QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#344773#7736. Red Black Treeucup-team992WA 204ms32580kbC++233.2kb2024-03-05 09:50:072024-03-05 09:50:07

Judging History

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

  • [2024-03-05 09:50:07]
  • 评测
  • 测评结果:WA
  • 用时:204ms
  • 内存:32580kb
  • [2024-03-05 09:50:07]
  • 提交

answer

//
// Created by codicon on 3/2/2024 at 6:08 PM.
//

// sum over nodes with > 1 child of (# children * dist to closest_leaf in subtree)
// = O(N)!!!

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5+1;

int n;
string s;

int ans[MAXN];

vector<int> adj[MAXN];

int ptr[MAXN];
pair<vector<int>, array<int, 2>> cost[MAXN]; // {cost, {reds, blacks} in chain above}

struct minq {
    deque<int> dq;
    queue<int> q;

    int min() {
        if (empty(dq)) {
            return 1e9;
        }
        return dq.front();
    }

    void push(int x) {
        q.push(x);
        while (!empty(dq) and dq.back() < x) {
            dq.pop_back();
        }
        dq.push_back(x);
    }

    void pop() {
        if (q.front() == dq.front()) {
            dq.pop_front();
        }
        q.pop();
    }
};

vector<int> reel_up(const pair<vector<int>, array<int, 2>>& cost_chain, int d) {
    vector<int> nc(d);

    auto [c, _] = cost_chain;
    auto [r, b] = _;

    minq left, right;
    int ladd = 0, radd = 0;
    for (int i = 0; i < d; i++) {
        // Left
        ladd++;
        // add
        if (b <= i and i < b + size(c)) {
            left.push(c[i-b] - ladd);
        }
        // remove
        if (b <= i-(r+1) and i-(r+1) < b + size(c)) {
            left.pop();
        }

        // Right
        radd--;
        // add
        if (b <= i+b and i+b < b + size(c)) {
            right.push(c[i+b-b]+b - radd);
        }
        // remove
        if (b <= i and i < b + size(c)) {
            right.pop();
        }

        nc[i] = min(left.min() + ladd, right.min() + radd);
    }

    return nc;
}

void solve(int c) {
    if (size(adj[c]) == 0) {
        ptr[c] = c;
        cost[c] = {{0}, {}};
        cost[c].second[s[c] == '1']++;

        ans[c] = 0;
    }
    else if (size(adj[c]) == 1) {
        int ne = adj[c][0];
        solve(ne);
        ptr[c] = ptr[ne];
        cost[ptr[c]].second[s[c] == '1']++;

        ans[c] = ans[ne];
    }
    else {
        int min_d = 1e9;

        for (auto ne: adj[c]) {
            solve(ne);
            min_d = min(min_d, (int)size(cost[ptr[ne]].first)
                               + cost[ptr[ne]].second[0] + cost[ptr[ne]].second[1]);
        }

        ptr[c] = c;
        cost[c].first.assign(min_d, 0);
        cost[c].second = {};
        cost[c].second[s[c] == '1']++;

        // O(N) amortized!!
        for (auto ne: adj[c]) {
            vector<int> ne_cost = reel_up(cost[ptr[ne]], min_d);
            for (int i = 0; i < min_d; i++) {
                cost[c].first[i] += ne_cost[i];
            }
        }

        ans[c] = *min_element(cost[c].first.begin(), cost[c].first.end());
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int t; cin >> t;
    while (t--) {
        cin >> n;

        cin >> s;

        for (int i = 0; i < n; i++) {
            adj[i].clear();
        }
        for (int i = 1; i <= n - 1; i++) {
            int p;
            cin >> p;
            p--;
            adj[p].push_back(i);
        }

        solve(0);

        for (int i = 0; i < n; i++) {
            cout << ans[i] << " \n"[i==n-1];
        }
    }
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3868kb

input:

2
9
101011110
1 1 3 3 3 6 2 2
4
1011
1 1 3

output:

4 1 2 0 0 0 0 0 0
2 0 0 0

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 204ms
memory: 32580kb

input:

6107
12
000000001000
1 2 3 2 5 4 4 7 3 8 11
19
1100111101111011110
1 2 1 1 4 5 2 4 3 2 2 7 10 2 11 3 15 5
7
0111110
1 1 2 2 1 5
3
000
1 1
7
1000011
1 2 3 3 5 4
7
0001001
1 1 1 3 5 3
8
00111000
1 1 3 2 5 2 7
11
11111110111
1 1 1 4 5 4 5 2 5 1
15
110101101000010
1 2 3 2 1 5 2 5 6 5 8 7 9 14
10
0101000...

output:

1 1 1 1 0 0 0 0 0 0 0 0
9 5 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0
2 0 1 0 0 0 0
3 1 0 0 0 0 0 0
4 0 0 2 1 0 0 0 0 0 0
4 4 0 0 2 0 0 0 0 0 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0
7 5 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
1 1 0 0 0
6 1 0 1 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0 0
6 4 ...

result:

wrong answer 2nd lines differ - expected: '6 2 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0', found: '9 5 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0'