Submission #855800

# Submission time Handle Problem Language Result Execution time Memory
855800 2023-10-01T20:13:29 Z tvladm2009 Two Currencies (JOI23_currencies) C++17
10 / 100
5000 ms 411232 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 100000 + 7;
const int K = 20;
const int B = 600;
int n;
int m;
int q;
vector<int> g[N];
pair<int, int> edges[N];
int dep[N];
int par[N];
int l[N];
int r[N];
int tab[K][N];
int tt = 0;
pair<int, int> updates[N];
ll sumToRoot[B][N];
ll prefSum[B][N];
int countToRoot[B][N];
int prefCount[B][N];

int get_bucket(int x) {
  return (x - 1) / B + 1;
}

struct segtree {
  int n;
  vector<ll> tree;
  vector<ll> lazy;

  void init(int nn) {
    n = nn;
    tree.resize(4 * n + 1);
    lazy.resize(4 * n + 1);
    for (int i = 1; i <= 4 * n; i++) {
      tree[i] = 0;
      lazy[i] = 0;
    }
  }

  void push(int v, int tl, int tr) {
    if (tl < tr) {
      lazy[2 * v] += lazy[v];
      lazy[2 * v + 1] += lazy[v];
    }
    tree[v] += lazy[v];
    lazy[v] = 0;
  }

  void applyRange(int v, int tl, int tr, int x, int y, ll val) {
    push(v, tl, tr);
    if (x <= tl && tr <= y) {
      lazy[v] += val;
      push(v, tl, tr);
      return;
    }
    int tm = (tl + tr) / 2;
    if (x <= tm) {
      applyRange(2 * v, tl, tm, x, min(tm, y), val);
    }
    if (tm + 1 <= y) {
      applyRange(2 * v + 1, tm + 1, tr, max(x, tm + 1), y, val);
    }
    push(2 * v, tl, tm);
    push(2 * v + 1, tm + 1, tr);
    tree[v] = tree[2 * v] + tree[2 * v + 1];
  }

  ll force(int v, int tl, int tr, int x, int y) {
    push(v, tl, tr);
    if (x <= tl && tr <= y) {
      return tree[v];
    }
    int tm = (tl + tr) / 2;
    if (x <= tm && y <= tm) {
      return force(2 * v, tl, tm, x, y);
    } else if (tm + 1 <= x && tm + 1 <= y) {
      return force(2 * v + 1, tm + 1, tr, x, y);
    } else {
      return force(2 * v, tl, tm, x, tm) + force(2 * v + 1, tm + 1, tr, tm + 1, tr);
    }
  }
};

void build(int a, int p = 0) {
  l[a] = ++tt;
  tab[0][a] = p;
  for (int k = 1; k < K; k++) {
    tab[k][a] = tab[k - 1][tab[k - 1][a]];
  }
  for (auto &b : g[a]) {
    if (b != p) {
      par[b] = a;
      dep[b] = dep[a] + 1;
      build(b, a);
    }
  }
  r[a] = tt;
}

int lca(int x, int y) {
  if (dep[x] < dep[y]) {
    swap(x, y);
  }
  for (int k = K - 1; k >= 0; k--) {
    if (dep[x] - (1 << k) >= dep[y]) {
      x = tab[k][x];
    }
  }
  if (x == y) {
    return x;
  }
  for (int k = K - 1; k >= 0; k--) {
    if (tab[k][x] != tab[k][y]) {
      x = tab[k][x];
      y = tab[k][y];
    }
  }
  return tab[0][x];
}

bool is_ancestor(int x, int y) {
  return l[x] <= l[y] && r[y] <= r[x];
}

ll getToRoot(int when, int node) {
  if (node == 0) {
    return 0;
  }
  int bucket = get_bucket(when) - 1;
  ll sol = prefSum[bucket][node];
  for (int i = B * bucket + 1; i <= when; i++) {
    ll val = updates[i].first;
    int x = updates[i].second;
    if (is_ancestor(x, node)) {
      sol += val;
    }
  }
  return sol;
}

ll get_sum(int when, int x, int y) {
  int z = lca(x, y);
  return getToRoot(when, x) + getToRoot(when, y) - 2 * getToRoot(when, z);
}

ll getToRoot2(int when, int node) {
  if (node == 0) {
    return 0;
  }
  int bucket = get_bucket(when) - 1;
  ll sol = prefCount[bucket][node];
  for (int i = B * bucket + 1; i <= when; i++) {
    int x = updates[i].second;
    if (is_ancestor(x, node)) {
      sol++;
    }
  }
  return sol;
}

ll get_count(int when, int x, int y) {
  int z = lca(x, y);
  return getToRoot2(when, x) + getToRoot2(when, y) - 2 * getToRoot2(when, z);
}

struct T {
  int s;
  int t;
  int x;
  ll y;
  int low;
  int high;
  int mid;
  int sol;
  int id;
};

vector<T> queries;
int moment[N];
int print[N];

void get_moments() {
  int mm = m;
  while (m > 0) {
    m /= 2;
    int k = 0;
    vector<T> new_queries, others;
    while (k < (int) queries.size()) {
      ll now = get_sum(queries[k].mid, queries[k].s, queries[k].t);
      if (now <= queries[k].y) {
        queries[k].sol = queries[k].mid;
        queries[k].low = queries[k].mid + 1;
        queries[k].mid = (queries[k].low + queries[k].high) / 2;
        others.push_back(queries[k]);
      } else {
        queries[k].high = queries[k].mid;
        queries[k].mid = (queries[k].low + queries[k].high) / 2;
        new_queries.push_back(queries[k]);
      }
      k++;
    }
    for (auto &it : others) {
      new_queries.push_back(it);
    }
    others.clear();
    queries = new_queries;
  }
  m = mm;
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

/// freopen("input.txt", "r", stdin);

  cin >> n >> m >> q;
  for (int i = 1; i < n; i++) {
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
    edges[i] = {x, y};
  }
  build(1);
  for (int i = 1; i <= m; i++) {
    ll road, val;
    cin >> road >> val;
    int x = edges[road].first;
    int y = edges[road].second;
    if (dep[x] < dep[y]) {
      swap(x, y);
    }
    updates[i] = {val, x};
  }
  sort(updates + 1, updates + m + 1);


  { /// for sum
    for (int bucket = 1; bucket <= get_bucket(m); bucket++) {
      segtree tree;
      tree.init(n);
      for (int i = (bucket - 1) * B + 1; i <= bucket * B; i++) {
        ll val = updates[i].first;
        int x = updates[i].second;
        if (x != 0) {
          tree.applyRange(1, 1, n, l[x], r[x], val);
        }
      }
      for (int i = 1; i <= n; i++) {
        sumToRoot[bucket][i] = tree.force(1, 1, n, l[i], l[i]);
      }
    }
    for (int i = 1; i <= n; i++) {
      for (int bucket = 1; bucket <= get_bucket(m); bucket++) {
        prefSum[bucket][i] = prefSum[bucket - 1][i] + sumToRoot[bucket][i];
      }
    }
  }
  { /// for cnt
    for (int bucket = 1; bucket <= get_bucket(m); bucket++) {
      segtree tree;
      tree.init(n);
      for (int i = (bucket - 1) * B + 1; i <= bucket * B; i++) {
        int x = updates[i].second;
        if (x != 0) {
          tree.applyRange(1, 1, n, l[x], r[x], 1);
        }
      }
      for (int i = 1; i <= n; i++) {
        countToRoot[bucket][i] = tree.force(1, 1, n, l[i], l[i]);
      }
    }
    for (int i = 1; i <= n; i++) {
      for (int bucket = 1; bucket <= get_bucket(m); bucket++) {
        prefCount[bucket][i] = prefCount[bucket - 1][i] + countToRoot[bucket][i];
      }
    }
  }

  for (int i = 0; i < q; i++) {
    T aux;
    cin >> aux.s >> aux.t >> aux.x >> aux.y;
    aux.low = 1;
    aux.high = m;
    aux.mid = (m + 1) / 2;
    aux.sol = 0;
    aux.id = i + 1;
    queries.push_back(aux);
  }
  get_moments();
  for (int iq = 0; iq < q; iq++) {
    int s = queries[iq].s;
    int t = queries[iq].t;
    int x = queries[iq].x;
    ll y = queries[iq].y;

    int sol = queries[iq].sol;
    int z = lca(s, t);
    int payed = get_count(sol, s, t);
    int total = get_count(m, s, t);
    int keep = x - (total - payed);
    if (keep < 0) {
      keep = -1;
    }
    print[queries[iq].id] = keep;
  }
  for (int i = 1; i <= q; i++) {
    cout << print[i] << "\n";
  }
  return 0;
}

Compilation message

currencies.cpp: In function 'int main()':
currencies.cpp:300:8: warning: unused variable 'y' [-Wunused-variable]
  300 |     ll y = queries[iq].y;
      |        ^
currencies.cpp:303:9: warning: unused variable 'z' [-Wunused-variable]
  303 |     int z = lca(s, t);
      |         ^
# Verdict Execution time Memory Grader output
1 Correct 3 ms 19804 KB Output is correct
2 Correct 3 ms 19804 KB Output is correct
3 Correct 3 ms 19804 KB Output is correct
4 Correct 3 ms 19804 KB Output is correct
5 Correct 35 ms 28604 KB Output is correct
6 Correct 55 ms 28684 KB Output is correct
7 Correct 46 ms 26620 KB Output is correct
8 Correct 66 ms 28648 KB Output is correct
9 Correct 62 ms 28664 KB Output is correct
10 Correct 76 ms 28776 KB Output is correct
11 Correct 70 ms 28652 KB Output is correct
12 Correct 65 ms 28680 KB Output is correct
13 Correct 64 ms 28776 KB Output is correct
14 Correct 69 ms 28760 KB Output is correct
15 Correct 82 ms 28644 KB Output is correct
16 Correct 73 ms 28684 KB Output is correct
17 Correct 69 ms 28644 KB Output is correct
18 Correct 70 ms 28648 KB Output is correct
19 Correct 57 ms 28664 KB Output is correct
20 Correct 60 ms 28992 KB Output is correct
21 Correct 57 ms 28688 KB Output is correct
22 Correct 57 ms 28664 KB Output is correct
23 Correct 55 ms 28648 KB Output is correct
24 Correct 58 ms 28660 KB Output is correct
25 Correct 56 ms 28768 KB Output is correct
26 Correct 81 ms 28680 KB Output is correct
27 Correct 38 ms 28600 KB Output is correct
28 Correct 43 ms 28652 KB Output is correct
29 Correct 30 ms 28700 KB Output is correct
30 Correct 59 ms 28668 KB Output is correct
31 Correct 61 ms 28668 KB Output is correct
32 Correct 56 ms 28664 KB Output is correct
33 Correct 57 ms 28728 KB Output is correct
34 Correct 57 ms 28760 KB Output is correct
35 Correct 56 ms 28764 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3 ms 19800 KB Output is correct
2 Correct 63 ms 28676 KB Output is correct
3 Correct 60 ms 28664 KB Output is correct
4 Correct 56 ms 28668 KB Output is correct
5 Execution timed out 5092 ms 395192 KB Time limit exceeded
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 19804 KB Output is correct
2 Correct 59 ms 28772 KB Output is correct
3 Correct 57 ms 28760 KB Output is correct
4 Correct 55 ms 28764 KB Output is correct
5 Correct 4106 ms 305080 KB Output is correct
6 Correct 4532 ms 254960 KB Output is correct
7 Execution timed out 5025 ms 411232 KB Time limit exceeded
8 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 19804 KB Output is correct
2 Correct 3 ms 19804 KB Output is correct
3 Correct 3 ms 19804 KB Output is correct
4 Correct 3 ms 19804 KB Output is correct
5 Correct 35 ms 28604 KB Output is correct
6 Correct 55 ms 28684 KB Output is correct
7 Correct 46 ms 26620 KB Output is correct
8 Correct 66 ms 28648 KB Output is correct
9 Correct 62 ms 28664 KB Output is correct
10 Correct 76 ms 28776 KB Output is correct
11 Correct 70 ms 28652 KB Output is correct
12 Correct 65 ms 28680 KB Output is correct
13 Correct 64 ms 28776 KB Output is correct
14 Correct 69 ms 28760 KB Output is correct
15 Correct 82 ms 28644 KB Output is correct
16 Correct 73 ms 28684 KB Output is correct
17 Correct 69 ms 28644 KB Output is correct
18 Correct 70 ms 28648 KB Output is correct
19 Correct 57 ms 28664 KB Output is correct
20 Correct 60 ms 28992 KB Output is correct
21 Correct 57 ms 28688 KB Output is correct
22 Correct 57 ms 28664 KB Output is correct
23 Correct 55 ms 28648 KB Output is correct
24 Correct 58 ms 28660 KB Output is correct
25 Correct 56 ms 28768 KB Output is correct
26 Correct 81 ms 28680 KB Output is correct
27 Correct 38 ms 28600 KB Output is correct
28 Correct 43 ms 28652 KB Output is correct
29 Correct 30 ms 28700 KB Output is correct
30 Correct 59 ms 28668 KB Output is correct
31 Correct 61 ms 28668 KB Output is correct
32 Correct 56 ms 28664 KB Output is correct
33 Correct 57 ms 28728 KB Output is correct
34 Correct 57 ms 28760 KB Output is correct
35 Correct 56 ms 28764 KB Output is correct
36 Correct 3 ms 19800 KB Output is correct
37 Correct 63 ms 28676 KB Output is correct
38 Correct 60 ms 28664 KB Output is correct
39 Correct 56 ms 28668 KB Output is correct
40 Execution timed out 5092 ms 395192 KB Time limit exceeded
41 Halted 0 ms 0 KB -