Advertisement
pasholnahuy

Сумма ребер

Jun 12th, 2023
601
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.84 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. int upper_log2(int n) {
  8.     int t = 1;
  9.     int ans = 0;
  10.     while (t <= n) {
  11.         t *= 2;
  12.         ++ans;
  13.     }
  14.     return ans;
  15. }
  16.  
  17. class Tree {
  18. public:
  19.     Tree(vector<int> &a, vector<int> cost) : costs(cost) {
  20.         graph.resize(a.size());
  21.         parent.resize(a.size(), vector<int>(upper_log2(a.size())));
  22.         sums.assign(a.size(), vector<int>(upper_log2(a.size()), 0));
  23.         tin.resize(a.size());
  24.         tout.resize(a.size());
  25.         for (int i = 0; i < a.size(); ++i) {
  26.             if (a[i] == -1) {
  27.                 root = i;
  28.             } else {
  29.                 graph[a[i]].push_back(i);
  30.             }
  31.         }
  32.     }
  33.  
  34.     bool Check(int parent, int child) {
  35.         return tin[parent] <= tin[child] && tout[child] <= tout[parent];
  36.     }
  37.  
  38.     int SummEdge(int a, int b) {
  39.         int summ = 0;
  40.         for (int i = parent[a].size() - 1; i >= 0; --i) {
  41.             if (!Check(parent[a][i], b)) {
  42.                 summ += sums[a][i];
  43.                 a = parent[a][i];
  44.             }
  45.         }
  46.         int summ2 = 0;
  47.         for (int i = parent[b].size() - 1; i >= 0; --i) {
  48.             if (!Check(parent[b][i], a)) {
  49.                 summ2 += sums[b][i];
  50.                 b = parent[b][i];
  51.             }
  52.         }
  53. //        cout << a << ' ' << minims[a][0] << ' ' << b << ' ' << minims[b][0] << endl;
  54.         if (Check(a, b)) {
  55.             return summ2 + sums[b][0];
  56.         }
  57.         if (Check(b, a)) {
  58.             summ + sums[a][0];
  59.         }
  60.         return summ + summ2 + sums[a][0] + sums[b][0];
  61.  
  62.     }
  63.  
  64.     void dfs() {
  65.         return dfs(root, 0);
  66.     }
  67.  
  68. private:
  69.     vector<vector<int>> graph;
  70.     vector<vector<int>> parent;
  71.     vector<vector<int>> sums;
  72.     vector<int> costs;
  73.     vector<int> tin;
  74.     vector<int> tout;
  75.     int time = 0;
  76.     int root;
  77.  
  78.     void dfs(int n, int prev) {
  79.         parent[n][0] = prev;
  80.         sums[n][0] = costs[n];
  81.         tin[n] = ++time;
  82.         for (int i = 1; i < parent[n].size(); ++i) {
  83.             parent[n][i] = parent[parent[n][i - 1]][i - 1];
  84.             sums[n][i] = sums[n][i - 1] + sums[parent[n][i - 1]][i - 1];
  85.         }
  86.         for (auto neigh: graph[n]) {
  87.             dfs(neigh, n);
  88.         }
  89.         tout[n] = ++time;
  90.     }
  91. };
  92.  
  93. int main() {
  94.     int n;
  95.     cin >> n;
  96.     vector<int> vec(n);
  97.     vector<int> cost(n);
  98.     vec[0] = -1;
  99.     cost[0] = 1e9;
  100.     for (size_t i = 1; i < n; ++i) {
  101.         cin >> vec[i] >> cost[i], --vec[i];
  102.     }
  103.     Tree tree(vec, cost);
  104.     tree.dfs();
  105.     int m;
  106.     cin >> m;
  107.     for (size_t i = 0; i < m; ++i) {
  108.         int a, b;
  109.         cin >> a >> b, --a, --b;
  110.         if (a == b){
  111.             cout << 0 << '\n';
  112.         } else {
  113.             cout << tree.SummEdge(a, b) << '\n';
  114.         }
  115.     }
  116.     return 0;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement