Submission #1035358

#TimeUsernameProblemLanguageResultExecution timeMemory
1035358juicyConstruction of Highway (JOI18_construction)C++17
100 / 100
429 ms28856 KiB
#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif

const int N = 1e5 + 5;

int n;
int c[N], pr[N], head[N], tin[N], sz[N], s[N], bot[N];
set<array<int, 2>> st[N];
vector<int> g[N];

void upd(int i, int x) {
  for (; i <= n; i += i & -i) {
    s[i] += x;
  }
}

int qry(int i) {
  int res = 0;
  for (; i; i -= i & -i) {
    res += s[i];
  }
  return res;
}

void dfs(int u) {
  for (int &v : g[u]) {
    if (v == pr[u]) {
      swap(v, g[u].back());
      g[u].pop_back();
      break;
    }
  }
  sz[u] = 1;
  for (int v : g[u]) {
    pr[v] = u;
    dfs(v);
    sz[u] += sz[v];
  }
}

int timer;

void hld(int u, int h) {
  tin[u] = ++timer;
  head[u] = h;
  bot[h] = timer;
  if (g[u].size()) {
    int x = *max_element(g[u].begin(), g[u].end(), [&](int i, int j) {
      return sz[i] < sz[j];
    });
    hld(x, h);
    for (int v : g[u]) {
      if (v != x) {
        hld(v, v);
      }
    }
  }
}

long long qry(int u, int x) {
  vector<array<int, 2>> cands;
  long long res = 0;
  for (; u; u = pr[head[u]]) {
    int h = head[u];
    auto it = st[h].lower_bound({tin[u] + 1, 0});
    assert(it != st[h].end());
    bool exist = (*it)[0] == tin[u] + 1; 
    --it;
    if (!exist) {
      st[h].insert({tin[u] + 1, (*it)[1]});
    }
    vector<array<int, 2>> nw;
    while (st[h].size() && (*(it = st[h].begin()))[0] <= tin[u]) {
      nw.push_back({(*next(it))[0] - (*it)[0], (*it)[1]});
      st[h].erase(it);
    }
    reverse(nw.begin(), nw.end());
    cands.insert(cands.end(), nw.begin(), nw.end());
    nw.clear();
    st[h].insert({tin[h], x});
  }
  for (auto [l, x] : cands) {
    res += (long long) qry(x - 1) * l;
    upd(x, l);
  }
  for (auto [l, x] : cands) {
    upd(x, -l);
  }
  cands.clear();
  return res;
}

int main() {
  ios::sync_with_stdio(false); cin.tie(nullptr);

  cin >> n;
  vector<int> comp;
  for (int i = 1; i <= n; ++i) {
    cin >> c[i];
    comp.push_back(c[i]);
  }
  vector<array<int, 2>> edges;
  for (int i = 1; i < n; ++i) {
    int u, v; cin >> u >> v;
    edges.push_back({u, v});
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1);
  hld(1, 1);
  sort(comp.begin(), comp.end());
  comp.erase(unique(comp.begin(), comp.end()), comp.end());
  for (int i = 1; i <= n; ++i) {
    int h = head[i];
    c[i] = lower_bound(comp.begin(), comp.end(), c[i]) - comp.begin() + 1;
    st[h].insert({tin[i], c[i]});
    if (bot[i]) {
      st[h].insert({bot[i] + 1, -1});
    }
  }
  for (auto [u, v] : edges) {
    cout << qry(u, c[v]) << "\n";
  }
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...