50分求条

P1600 [NOIP2016 提高组] 天天爱跑步

__mt19937__ @ 2025-01-01 16:55:15

#include <bits/stdc++.h>

#define endl '\n'

const int N = 3000010;
const int M = N << 1;
const int L = 18;

struct edge_node {

    int next, to;
} edge_vector[N];

std :: vector <std :: pair <int, int> > S[N], Q[N];

int _father[N][L], deep[N];
int bin1[M], bin2[M];

int answer[N], W[N], head[N];

int n, m, cnt;

template <typename _this>
void swap (_this & first, _this & second) {

    _this tmp = first;

    first = second;

    second = tmp;

    return ;
}

void add_edge (int _start_node, int _end_node) {

    ++ cnt;

    edge_vector[cnt].to = _end_node;
    edge_vector[cnt].next = head[_start_node];

    head[_start_node] = cnt;

    return ;
}

void init (int _this_node, int _father_node) {

    _father[_this_node][0] = _father_node;

    for (int i = 1; _father[_this_node][i - 1]; ++ i) {

        _father[_this_node][i] = _father[_father[_this_node][i - 1]][i - 1];
    }

    for (int i = head[_this_node]; i; i = edge_vector[i].next) {

        int visit = edge_vector[i].to;

        if (visit == _father_node) {

            continue;
        }

        deep[visit] = deep[_this_node] + 1;

        init (visit, _this_node);
    }

    return;
}

int LCA (int left, int right) {

    if (deep[left] < deep[right]) {

        swap (left, right);
    }

    for (int i = L; ~ i; -- i) {

        if (deep[left] - (1 << i) >= deep[right]) {

            left = _father[left][i];
        }
    }

    if (left == right) {

        return left;
    }

    for (int i = L; ~ i; -- i) {

        if (_father[left][i] != _father[right][i]) {

            left = _father[left][i];
            right = _father[right][i];
        }
    }

    return _father[left][0];
}

void update (int _start_, int _end_) {

    int P = LCA (_start_, _end_);

    S[_start_].push_back (std :: make_pair (deep[_start_], 1));
    S[_father[P][0]].push_back (std :: make_pair (deep[_start_], -1));

    Q[_end_].push_back (std :: make_pair (deep[_start_] - (deep[P] << 1) + n, 1));
    Q[P].push_back (std :: make_pair (deep[_start_] - (deep[P] << 1) + n, -1));

    return ;
}

void deep_first_search (int _this_node, int _father_node) {

    int V1 = W[_this_node] + deep[_this_node], V2 = deep[_this_node] - W[_this_node] + n;

    int P_first = bin1[V1], P_second = bin2[V2];

    for (int i = head[_this_node]; i; i = edge_vector[i].next) {

        int visit = edge_vector[i].to;

        if (visit == _father_node) {

            continue;
        }

        deep_first_search (visit, _this_node);
    }

    for (int i = 0; i < S[_this_node].size (); ++ i) {

        bin1[S[_this_node][i].first] += S[_this_node][i].second;
    }

    for (int i = 0; i < Q[_this_node].size (); ++ i) {

        bin2[Q[_this_node][i].first] += Q[_this_node][i].second;
    }

    answer[_this_node] = bin1[V1] + bin2[V2] - P_first - P_second;

    return ;
}

int main (void) {

    std :: ios :: sync_with_stdio (false);
    std :: cin.tie (nullptr);
    std :: cout.tie (nullptr);

    std :: cin >> n >> m;

    for (int i = 1; i < n; ++ i) {

        int st, ed;

        std :: cin >> st >> ed;

        add_edge (st, ed);
        add_edge (ed, st);
    }

    for (int i = 1; i <= n; ++ i) {

        std :: cin >> W[i];
    }

    init (1, 0);

    for (int i = 1; i <= m; ++ i) {

        int _s, _t;

        std :: cin >> _s >> _t;

        update (_s, _t);
    }

    deep_first_search (1, 0);

    for (int i = 1; i <= n; ++ i) {

        std :: cout << answer[i] << ' ';
    }

    return 0;
}

|