Advertisement
Josif_tepe

Untitled

Feb 29th, 2024
1,021
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.33 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. //#include <bits/stdc++.h>
  4. #include <cmath>
  5. #include <queue>
  6. #include <cstring>
  7. #include <algorithm>
  8. using namespace std;
  9. typedef long long ll;
  10. const int maxn = 30010;
  11. const int logn = 20;
  12. const int INF = 2e9;
  13. int up[maxn][logn], n;
  14. vector<pair<int, int>> graph[maxn];
  15. int depth[maxn], parent[maxn];
  16. int dp[logn][maxn];
  17. ll dist[maxn];
  18. int max_edge[logn][maxn], min_edge[logn][maxn];
  19. void dfs(int node, int prev, int level) {
  20.     depth[node] = level;
  21.     parent[node] = prev;
  22.     dp[0][node] = prev;
  23.     for(int i = 0; i < (int) graph[node].size(); i++) {
  24.         int neighbour = graph[node][i].first;
  25.         int weight = graph[node][i].second;
  26.         if(prev != neighbour) {
  27.             dist[neighbour] = dist[node] + weight;
  28.             min_edge[0][neighbour] = weight;
  29.             max_edge[0][neighbour] = weight;
  30.             dfs(neighbour, node, level + 1);
  31.         }
  32.     }
  33. }
  34.  
  35. void preprocess() {
  36.     memset(up, -1, sizeof up);
  37.    
  38.     for(int i = 0; i < n; i++) {
  39.         up[i][0] = parent[i];
  40.        
  41.     }
  42.     for(int j = 1; (1 << j) < n; j++) {
  43.         for(int i = 0; i < n; i++) {
  44.             if(up[i][j - 1] != -1) {
  45.                 up[i][j] = up[up[i][j - 1]][j - 1];
  46.             }
  47.         }
  48.     }
  49.  
  50. }
  51. int LCA(int a, int b) {
  52.     if(depth[a] > depth[b]) {
  53.         swap(a, b);
  54.     }
  55.     int diff = depth[b] - depth[a];
  56.     while(diff > 0) {
  57.         int pow = log2(diff);
  58.         b = up[b][pow];
  59.         diff -= (1 << pow);
  60.     }
  61.     if(b == a) {
  62.         return a;
  63.     }
  64.     for(int i = logn - 1; i >= 0; i--) {
  65.         if(up[a][i] != -1 and up[a][i] != up[b][i]) {
  66.            
  67.             a = up[a][i];
  68.             b = up[b][i];
  69.         }
  70.     }
  71.     return parent[a];
  72. }
  73. void preprocess_max_min() {
  74.     for(int i = 1; i < logn; i++) {
  75.         for(int j = 1; j <= n; j++) {
  76.             dp[i][j] = dp[i - 1][dp[i - 1][j]];
  77.             max_edge[i][j] = max(max_edge[i - 1][j], max_edge[i - 1][dp[i - 1][j]]);
  78.             min_edge[i][j] = min(min_edge[i - 1][j], min_edge[i - 1][dp[i - 1][j]]);
  79.         }
  80.     }
  81. }
  82. pair<int, int> get_max_min_edge(int a, int b) {
  83.     if(depth[b] < depth[a]) {
  84.         swap(a, b);
  85.     }
  86.     int res_min = INF, res_max = -INF;
  87.     int diff = depth[b] - depth[a];
  88.     while(diff > 0) {
  89.         int pow = log2(diff);
  90.         res_max = max(res_max, max_edge[pow][b]);
  91.         res_min = min(res_min, min_edge[pow][b]);
  92.         b = dp[pow][b];
  93.         diff -= (1 << pow);
  94.     }
  95.     while(a != b) {
  96.         int i = log2(depth[a]);
  97.         while(i > 0 and dp[i][a] == dp[i][b]) {
  98.             i--;
  99.         }
  100.         res_max = max(res_max, max_edge[i][a]);
  101.         res_max = max(res_max, max_edge[i][b]);
  102.        
  103.         res_min = min(res_min, min_edge[i][a]);
  104.         res_min = min(res_min, min_edge[i][b]);
  105.         a = dp[i][a];
  106.         b = dp[i][b];
  107.     }
  108.     return make_pair(res_min, res_max);
  109. }
  110. int main() {
  111.     ios_base::sync_with_stdio(false);
  112.     int q;
  113.     cin >> n >> q;
  114.     for(int i = 1; i < n; i++) {
  115.         int a, b, c;
  116.         cin >> a >> b >> c;
  117.         a--; b--;
  118.         graph[a].push_back(make_pair(b, c));
  119.         graph[b].push_back(make_pair(a, c));
  120.     }
  121.     for(int i = 0; i < n; i++) {
  122.         for(int j = 0; j < logn; j++) {
  123.             max_edge[j][i] = -INF;
  124.             min_edge[j][i] = INF;
  125.         }
  126.     }
  127.     dfs(0, -1, 0);
  128.     preprocess();
  129.     preprocess_max_min();
  130.     ll ivan = 0, martin = 0;
  131.    
  132.     for(int i = 1; i <= q; i++) {
  133.         int a, b, c;
  134.         cin >> a >> b >> c;
  135.         a--; b--;
  136.        
  137.         int lca = LCA(a, b);
  138.         ll d = dist[a] + dist[b] - 2LL * dist[lca];
  139.         pair<int, int> p = get_max_min_edge(a, b);
  140.        
  141.         int neg = -1 * p.first * c;
  142.         int pos = p.second * c;
  143.         ll d1 = d, d2 = d;
  144.        
  145.             d1 -= p.first;
  146.             d1 += neg;
  147.        
  148.        
  149.             d2 -= p.second;
  150.             d2 += pos;
  151.        
  152.         d = max(d1, d2);
  153.         if(i % 2 == 1) {
  154.             ivan += d;
  155.            
  156.         }
  157.         else {
  158.             martin += d;
  159.         }
  160.     }
  161.     if(ivan == martin) {
  162.         cout << "=" << endl;
  163.     }
  164.     else if(ivan > martin) {
  165.         cout << "Ivan " << ivan - martin << endl;
  166.     }
  167.     else {
  168.         cout << "Martin " << martin - ivan << endl;
  169.     }
  170.     return 0;
  171. }
  172.  
  173.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement