Submission #2337715


Source Code Expand

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < int(n); ++ (i))
#define ALL(x) begin(x), end(x)
using ll = long long;
using namespace std;
template <class T> inline void chmax2(T & a1, T & a2, T const & b) { if (a1 < b) { a2 = a1; a1 = b; } else if (a2 < b) { a2 = b; } }

/**
 * @brief fold a rooted tree (木DP)
 * @note O(N op) time
 * @note O(N) space, not recursive
 * @note
 *     struct tree_operation {
 *         typedef int type;
 *         type operator () (int i, vector<pair<int, type> > const & args);
 *     };
 */
template <typename TreeOperation>
vector<typename TreeOperation::type> fold_rooted_tree(vector<vector<int> > const & g, int root, TreeOperation op = TreeOperation()) {
    int n = g.size();
    vector<typename TreeOperation::type> data(n);
    stack<tuple<bool, int, int> > stk;
    stk.emplace(false, root, -1);
    while (not stk.empty()) {
        bool state; int x, parent; tie(state, x, parent) = stk.top(); stk.pop();
        if (not state) {
            stk.emplace(true, x, parent);
            for (int y : g[x]) if (y != parent) {
                stk.emplace(false, y, x);
            }
        } else {
            vector<pair<int, typename TreeOperation::type const &> > args;
            for (int y : g[x]) if (y != parent) {
                args.emplace_back(y, data[y]);
            }
            data[x] = op(x, args);
        }
    };
    return data;
}

/**
 * @brief rerooting (全方位木DP)
 * @note O(N op) time
 * @note O(N) space, not recursive
 * @note
 *     struct tree_operation {
 *         typedef int type;
 *         type      add(int i, type data_i, int j, type data_j);  // add    a subtree j to   the root i
 *         type subtract(int i, type data_i, int j, type data_j);  // remove a subtree j from the root i
 *     };
 * @note if add & subtract are slow, you can merge them
 */
template <typename TreeOperation>
vector<typename TreeOperation::type> reroot_folded_rooted_tree(vector<typename TreeOperation::type> data, vector<vector<int> > const & g, int root, TreeOperation op = TreeOperation()) {
    stack<pair<int, int> > stk;
    stk.emplace(root, -1);
    while (not stk.empty()) {
        int x, parent; tie(x, parent) = stk.top(); stk.pop();
        if (parent != -1) {
            typename TreeOperation::type data_parent = {};
            data_parent.self = data[parent].self;  // modified
            op.subtract(parent, data_parent, x, data[x]);
            op.add(x, data[x], parent, data_parent);
        }
        for (int y : g[x]) if (y != parent) {
            stk.emplace(y, x);
        }
    }
    return data;
}

struct node_t {
    int height;
    int second_height;
    int has_favorite;
};
struct tree_operation {
    typedef struct {
        node_t self;
        map<int, node_t> sub;
    } type;
    vector<bool> s;
    tree_operation(vector<bool> const & s) : s(s) {}
    type operator () (int i, vector<pair<int, type const &> > const & args) {
        type data = {};
        data.self.height = 1;
        data.self.has_favorite = s[i];
        for (auto const & arg : args) {
            add(i, data, arg.first, arg.second);
        }
        return data;
    }
    void add(int i, type & data_i, int j, type const & data_j) {  // add a subtree j to the root i
        chmax2(data_i.self.height, data_i.self.second_height, 1 + data_j.self.height);
        data_i.self.has_favorite += data_j.self.has_favorite;
        data_i.sub[j] = data_j.self;
    }
    void subtract(int i, type & data_i, int j, type const & data_j) {  // remove a subtree j from the root i
        if (data_i.self.height == 1 + data_j.self.height) data_i.self.height = data_i.self.second_height;
        data_i.self.has_favorite -= data_j.self.has_favorite;
    }
};
ll solve(int n, vector<vector<int> > const & g, vector<bool> const & s) {
    constexpr int root = 0;
    auto data = reroot_folded_rooted_tree(fold_rooted_tree(g, 0, tree_operation(s)), g, root, tree_operation(s));
    ll cnt = 0;
    REP (i, n) {
        int degree = g[i].size();
        if (degree == 1) {
            cnt += s[i];
        } else {
            vector<int> order = g[i];
            sort(ALL(order), [&](int j1, int j2) { return data[i].sub[j1].height < data[i].sub[j2].height; });
            int r = data[i].sub[order[degree - 2]].height + 1;
            int l = r;
            if (s[i]) {
                l = 0;
            } else {
                for (int j : order) {
                    if (data[i].sub[j].has_favorite) {
                        l = data[i].sub[j].height;
                        break;
                    }
                }
            }
            cnt += max(0, r - l);
        }
    }
    REP (i, n) {
        for (int j : g[i]) if (i < j) {
            int i_height = data[j].sub[i].height;
            int j_height = data[i].sub[j].height;
            if (i_height < j_height) {
                cnt += bool(data[j].sub[i].has_favorite);
            } else if (i_height > j_height) {
                cnt += bool(data[i].sub[j].has_favorite);
            } else {
                cnt += bool(data[i].sub[j].has_favorite or data[j].sub[i].has_favorite);
            }
        }
    }
    return cnt;
}

int main() {
    int n; cin >> n;
    vector<vector<int> > g(n);
    REP (i, n - 1) {
        int a, b; cin >> a >> b;
        -- a; -- b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    vector<bool> s(n);
    REP (i, n) {
        char c; cin >> c;
        s[i] = c - '0';
    }
    ll answer = solve(n, g, s);
    cout << answer << endl;
    return 0;
}

Submission Info

Submission Time
Task F - Black Radius
User kimiyuki
Language C++14 (GCC 5.4.1)
Score 1900
Code Size 5578 Byte
Status AC
Exec Time 1436 ms
Memory 52504 KB

Judge Result

Set Name Sample Subtask All
Score / Max Score 0 / 0 1300 / 1300 600 / 600
Status
AC × 3
AC × 31
AC × 81
Set Name Test Cases
Sample 0_00.txt, 0_01.txt, 0_02.txt
Subtask 0_01.txt, 1_00.txt, 1_01.txt, 1_02.txt, 1_03.txt, 1_04.txt, 1_05.txt, 1_06.txt, 1_07.txt, 1_08.txt, 1_09.txt, 1_10.txt, 1_11.txt, 1_12.txt, 1_13.txt, 1_14.txt, 1_15.txt, 1_16.txt, 1_17.txt, 1_18.txt, 1_19.txt, 1_20.txt, 1_21.txt, 1_22.txt, 1_23.txt, 1_24.txt, 1_25.txt, 1_26.txt, 1_27.txt, 1_28.txt, 1_29.txt
All 0_00.txt, 0_01.txt, 0_02.txt, 1_00.txt, 1_01.txt, 1_02.txt, 1_03.txt, 1_04.txt, 1_05.txt, 1_06.txt, 1_07.txt, 1_08.txt, 1_09.txt, 1_10.txt, 1_11.txt, 1_12.txt, 1_13.txt, 1_14.txt, 1_15.txt, 1_16.txt, 1_17.txt, 1_18.txt, 1_19.txt, 1_20.txt, 1_21.txt, 1_22.txt, 1_23.txt, 1_24.txt, 1_25.txt, 1_26.txt, 1_27.txt, 1_28.txt, 1_29.txt, 2_00.txt, 2_01.txt, 2_02.txt, 2_03.txt, 2_04.txt, 2_05.txt, 2_06.txt, 2_07.txt, 2_08.txt, 2_09.txt, 2_10.txt, 2_11.txt, 2_12.txt, 2_13.txt, 2_14.txt, 2_15.txt, 2_16.txt, 2_17.txt, 2_18.txt, 2_19.txt, 2_20.txt, 2_21.txt, 2_22.txt, 2_23.txt, 2_24.txt, 2_25.txt, 2_26.txt, 2_27.txt, 2_28.txt, 2_29.txt, 2_30.txt, 2_31.txt, 2_32.txt, 2_33.txt, 2_34.txt, 2_35.txt, 2_36.txt, 2_37.txt, 2_38.txt, 2_39.txt, 2_40.txt, 2_41.txt, 2_42.txt, 2_43.txt, 2_44.txt, 2_45.txt, 2_46.txt, 2_47.txt
Case Name Status Exec Time Memory
0_00.txt AC 1 ms 256 KB
0_01.txt AC 1 ms 256 KB
0_02.txt AC 1 ms 256 KB
1_00.txt AC 1 ms 256 KB
1_01.txt AC 451 ms 48768 KB
1_02.txt AC 441 ms 48768 KB
1_03.txt AC 450 ms 48768 KB
1_04.txt AC 788 ms 49620 KB
1_05.txt AC 1368 ms 50428 KB
1_06.txt AC 442 ms 49152 KB
1_07.txt AC 437 ms 49152 KB
1_08.txt AC 434 ms 49152 KB
1_09.txt AC 448 ms 48896 KB
1_10.txt AC 438 ms 48000 KB
1_11.txt AC 443 ms 48000 KB
1_12.txt AC 437 ms 47232 KB
1_13.txt AC 462 ms 48768 KB
1_14.txt AC 450 ms 48384 KB
1_15.txt AC 453 ms 48768 KB
1_16.txt AC 472 ms 48640 KB
1_17.txt AC 463 ms 48768 KB
1_18.txt AC 454 ms 48256 KB
1_19.txt AC 447 ms 48384 KB
1_20.txt AC 456 ms 48000 KB
1_21.txt AC 460 ms 48768 KB
1_22.txt AC 610 ms 49072 KB
1_23.txt AC 554 ms 48980 KB
1_24.txt AC 508 ms 48672 KB
1_25.txt AC 680 ms 49264 KB
1_26.txt AC 524 ms 47980 KB
1_27.txt AC 741 ms 49268 KB
1_28.txt AC 903 ms 49572 KB
1_29.txt AC 640 ms 49060 KB
2_00.txt AC 1 ms 256 KB
2_01.txt AC 445 ms 48768 KB
2_02.txt AC 463 ms 48768 KB
2_03.txt AC 471 ms 48768 KB
2_04.txt AC 457 ms 48768 KB
2_05.txt AC 442 ms 48768 KB
2_06.txt AC 441 ms 48784 KB
2_07.txt AC 437 ms 48768 KB
2_08.txt AC 440 ms 48768 KB
2_09.txt AC 454 ms 48768 KB
2_10.txt AC 792 ms 49620 KB
2_11.txt AC 791 ms 49620 KB
2_12.txt AC 795 ms 49620 KB
2_13.txt AC 1436 ms 50372 KB
2_14.txt AC 1293 ms 52504 KB
2_15.txt AC 1389 ms 50356 KB
2_16.txt AC 436 ms 49152 KB
2_17.txt AC 443 ms 49152 KB
2_18.txt AC 440 ms 49152 KB
2_19.txt AC 440 ms 49152 KB
2_20.txt AC 434 ms 49152 KB
2_21.txt AC 438 ms 49152 KB
2_22.txt AC 438 ms 49152 KB
2_23.txt AC 445 ms 49152 KB
2_24.txt AC 431 ms 49152 KB
2_25.txt AC 458 ms 48896 KB
2_26.txt AC 458 ms 48896 KB
2_27.txt AC 454 ms 48896 KB
2_28.txt AC 441 ms 48640 KB
2_29.txt AC 454 ms 48512 KB
2_30.txt AC 449 ms 48512 KB
2_31.txt AC 442 ms 48640 KB
2_32.txt AC 473 ms 49024 KB
2_33.txt AC 448 ms 48768 KB
2_34.txt AC 444 ms 48000 KB
2_35.txt AC 420 ms 47632 KB
2_36.txt AC 440 ms 48256 KB
2_37.txt AC 452 ms 48384 KB
2_38.txt AC 445 ms 48384 KB
2_39.txt AC 440 ms 48512 KB
2_40.txt AC 663 ms 49188 KB
2_41.txt AC 480 ms 48692 KB
2_42.txt AC 782 ms 48660 KB
2_43.txt AC 497 ms 49000 KB
2_44.txt AC 817 ms 49020 KB
2_45.txt AC 1068 ms 49828 KB
2_46.txt AC 1096 ms 49712 KB
2_47.txt AC 675 ms 48888 KB