#include #define PROBLEM "https://yukicoder.me/problems/no/1637" #include #include #include #include #include #include #include namespace mtd { template class Graph { using Edge = std::pair; using Edges = std::vector; const int m_n; std::vector m_graph; public: Graph(int n) : m_n(n), m_graph(n) {} Graph(const std::vector& edges) : m_n(edges.size()), m_graph(edges) {} auto addEdge(const Node& f, const Node& t, const Cost& c = 1) { m_graph[f].emplace_back(t, c); } auto addEdgeUndirected(const Node& f, const Node& t, const Cost& c = 1) { addEdge(f, t, c); addEdge(t, f, c); } auto getEdges(const Node& from) const { class EdgesRange { const typename Edges::const_iterator b, e; public: EdgesRange(const Edges& edges) : b(edges.begin()), e(edges.end()) {} auto begin() const { return b; } auto end() const { return e; } }; return EdgesRange(m_graph[from]); } auto getEdges() const { std::deque> edges; for (Node from : std::views::iota(0, m_n)) { for (const auto& [to, c] : getEdges(from)) { edges.emplace_back(from, to, c); } } return edges; } auto getEdgesExcludeCost() const { std::deque> edges; for (Node from : std::views::iota(0, m_n)) { for (const auto& [to, _] : getEdges(from)) { edges.emplace_back(from, to); } } return edges; } auto reverse() const { auto rev = Graph(m_n); for (const auto& [from, to, c] : getEdges()) { rev.addEdge(to, from, c); } return rev; } auto size() const { return m_n; }; auto debug(bool directed = false) const { for (const auto& [f, t, c] : getEdges()) { if (f < t || directed) { std::cout << f << " -> " << t << ": " << c << std::endl; } } } };} namespace mtd { template class EulerTour { const std::vector m_tour; const std::vector> m_appear; auto constructTour(const Graph& tree, Node root) const { auto n = tree.size(); std::vector tour; std::stack stk; std::vector used(n); stk.emplace(root); while (!stk.empty()) { auto from = stk.top(); tour.emplace_back(from); stk.pop(); if (used[from]) { continue; } stk.emplace(from); used[from] = true; for (auto [to, _] : tree.getEdges(from)) { if (!used[to]) { stk.emplace(to); } } } return tour; } auto constructAppear(int n) const { std::vector> appear(n, {-1, -1}); for (int i = 0; i < 2 * n; ++i) { if (appear[m_tour[i]].first == -1) { appear[m_tour[i]].first = i; } else { appear[m_tour[i]].second = i; } } return appear; } public: EulerTour(const Graph& tree, Node root = 0) : m_tour(constructTour(tree, root)), m_appear(constructAppear(tree.size())) {} auto lessOrder(int li, int ri) const { return m_appear[li].first < m_appear[ri].first; } auto isSon(Node son, Node parent) { return m_appear[parent].first < m_appear[son].first && m_appear[son].second < m_appear[parent].second; } auto range(Node u) const { return m_appear[u]; } };} signed main() { std::cin.tie(0); std::ios::sync_with_stdio(0); int n, q; std::cin >> n >> q; auto tree = mtd::Graph<>(n); for ([[maybe_unused]] auto _ : std::views::iota(0, n - 1)) { int a, b; std::cin >> a >> b; tree.addEdgeUndirected(a - 1, b - 1); } auto et = mtd::EulerTour(tree); std::vector size(n); for (auto i : std::views::iota(0, n)) { auto [l, r] = et.range(i); size[i] = (r - l + 1) / 2; } long long ans = 0; for ([[maybe_unused]] auto _ : std::views::iota(0, q)) { int p; long long x; std::cin >> p >> x; ans += x * size[p - 1]; std::cout << ans << std::endl; } }