Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- //#include <bits/stdc++.h>
- #include <cmath>
- #include <queue>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- typedef long long ll;
- const int maxn = 30010;
- const int logn = 20;
- const int INF = 2e9;
- int up[maxn][logn], n;
- vector<pair<int, int>> graph[maxn];
- int depth[maxn], parent[maxn];
- int dp[logn][maxn];
- ll dist[maxn];
- int max_edge[logn][maxn], min_edge[logn][maxn];
- void dfs(int node, int prev, int level) {
- depth[node] = level;
- parent[node] = prev;
- dp[0][node] = prev;
- for(int i = 0; i < (int) graph[node].size(); i++) {
- int neighbour = graph[node][i].first;
- int weight = graph[node][i].second;
- if(prev != neighbour) {
- dist[neighbour] = dist[node] + weight;
- min_edge[0][neighbour] = weight;
- max_edge[0][neighbour] = weight;
- dfs(neighbour, node, level + 1);
- }
- }
- }
- void preprocess() {
- memset(up, -1, sizeof up);
- for(int i = 0; i < n; i++) {
- up[i][0] = parent[i];
- }
- for(int j = 1; (1 << j) < n; j++) {
- for(int i = 0; i < n; i++) {
- if(up[i][j - 1] != -1) {
- up[i][j] = up[up[i][j - 1]][j - 1];
- }
- }
- }
- }
- int LCA(int a, int b) {
- if(depth[a] > depth[b]) {
- swap(a, b);
- }
- int diff = depth[b] - depth[a];
- while(diff > 0) {
- int pow = log2(diff);
- b = up[b][pow];
- diff -= (1 << pow);
- }
- if(b == a) {
- return a;
- }
- for(int i = logn - 1; i >= 0; i--) {
- if(up[a][i] != -1 and up[a][i] != up[b][i]) {
- a = up[a][i];
- b = up[b][i];
- }
- }
- return parent[a];
- }
- void preprocess_max_min() {
- for(int i = 1; i < logn; i++) {
- for(int j = 1; j <= n; j++) {
- dp[i][j] = dp[i - 1][dp[i - 1][j]];
- max_edge[i][j] = max(max_edge[i - 1][j], max_edge[i - 1][dp[i - 1][j]]);
- min_edge[i][j] = min(min_edge[i - 1][j], min_edge[i - 1][dp[i - 1][j]]);
- }
- }
- }
- pair<int, int> get_max_min_edge(int a, int b) {
- if(depth[b] < depth[a]) {
- swap(a, b);
- }
- int res_min = INF, res_max = -INF;
- int diff = depth[b] - depth[a];
- while(diff > 0) {
- int pow = log2(diff);
- res_max = max(res_max, max_edge[pow][b]);
- res_min = min(res_min, min_edge[pow][b]);
- b = dp[pow][b];
- diff -= (1 << pow);
- }
- while(a != b) {
- int i = log2(depth[a]);
- while(i > 0 and dp[i][a] == dp[i][b]) {
- i--;
- }
- res_max = max(res_max, max_edge[i][a]);
- res_max = max(res_max, max_edge[i][b]);
- res_min = min(res_min, min_edge[i][a]);
- res_min = min(res_min, min_edge[i][b]);
- a = dp[i][a];
- b = dp[i][b];
- }
- return make_pair(res_min, res_max);
- }
- int main() {
- ios_base::sync_with_stdio(false);
- int q;
- cin >> n >> q;
- for(int i = 1; i < n; i++) {
- int a, b, c;
- cin >> a >> b >> c;
- a--; b--;
- graph[a].push_back(make_pair(b, c));
- graph[b].push_back(make_pair(a, c));
- }
- for(int i = 0; i < n; i++) {
- for(int j = 0; j < logn; j++) {
- max_edge[j][i] = -INF;
- min_edge[j][i] = INF;
- }
- }
- dfs(0, -1, 0);
- preprocess();
- preprocess_max_min();
- ll ivan = 0, martin = 0;
- for(int i = 1; i <= q; i++) {
- int a, b, c;
- cin >> a >> b >> c;
- a--; b--;
- int lca = LCA(a, b);
- ll d = dist[a] + dist[b] - 2LL * dist[lca];
- pair<int, int> p = get_max_min_edge(a, b);
- int neg = -1 * p.first * c;
- int pos = p.second * c;
- ll d1 = d, d2 = d;
- d1 -= p.first;
- d1 += neg;
- d2 -= p.second;
- d2 += pos;
- d = max(d1, d2);
- if(i % 2 == 1) {
- ivan += d;
- }
- else {
- martin += d;
- }
- }
- if(ivan == martin) {
- cout << "=" << endl;
- }
- else if(ivan > martin) {
- cout << "Ivan " << ivan - martin << endl;
- }
- else {
- cout << "Martin " << martin - ivan << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement