QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#136049#6350. MITRedDiamondWA 2ms21892kbC++145.4kb2023-08-06 20:04:522023-08-06 20:04:56

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-06 20:04:56]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:21892kb
  • [2023-08-06 20:04:52]
  • 提交

answer

#include <bits/stdc++.h>/// to be continued

using namespace std;

typedef long long ll;
const int N = (int) 1e5 + 7;
const int K = 20;
const ll INF = (ll) 1e18;
int tin[N];
int tout[N];
int who[N];
int par[N];
int tab[K][N];
int depth[N];
ll dist[N];
ll sol[N];
vector<pair<int, ll>> g[N];
int n;

int tt = 0;

void dfs(int a, int p = 0) {
  tin[a] = ++tt;
  who[tt] = a;
  par[a] = p;
  for (auto &b : g[a]) {
    if (b.first == p) {
      continue;
    }
    depth[b.first] = dist[a] + 1;
    dist[b.first] = dist[a] + b.second;
    dfs(b.first, a);
  }
  tout[a] = tt;
}

int lca(int a, int b) {
  if (depth[a] < depth[b]) {
    swap(a, b);
  }
  for (int k = K - 1; k >= 0; k--) {
    if (depth[b] + (1 << k) <= depth[a]) {
      b = tab[k][b];
    }
  }
  if (a == b) {
    return a;
  }
  for (int k = K - 1; k >= 0; k--) {
    if (tab[k][a] != tab[k][b]) {
      a = tab[k][a];
      b = tab[k][b];
    }
  }
  return tab[0][a];
}

ll distance(int a, int b) {
  return dist[a] + dist[b] - dist[lca(a, b)];
}

int aib[N];

void add(int i, int x) {
  while (i < N) {
    aib[i] += x;
    i += i & (-i);
  }
}

int get(int i) {
  int sol = 0;
  while (i) {
    sol += aib[i];
    i -= i & (-i);
  }
  return sol;
}

int kth(int k) {
  int pos = 0;
  int cnt = 0;
  for (int kk = K - 1; kk >= 0; kk--) {
    if (pos + (1 << kk) <= k && cnt + aib[pos + (1 << kk)] < k) {
      cnt += aib[pos + (1 << kk)];
      pos += (1 << kk);
    }
  }
  pos++;
  return who[pos];
}

int jump(int a, int sz) {
  int aux = get(tout[a]) - get(tin[a] - 1);
  if (aux >= sz) {
    return a;
  } else {
    for (int k = K - 1; k >= 0; k--) {
      int p = tab[k][a];
      if (p != 0) {
        int auxx = get(tout[p]) - get(tin[p] - 1);
        if (auxx < sz) {
          a = p;
        }
      }
    }
    return tab[0][a];
  }
}

vector<int> centroid;

vector<int> getcentroid(int k) {
  int mid = (k / 2 + 1);
  int cen1 = jump(mid, (k + 1) / 2);
  int sum1 = get(tout[cen1]) - get(tin[cen1] - 1);
  if (k % 2 == 1) {
    return {cen1};
  }
  int one = kth(1);
  int cen2 = jump(one, (k + 1) / 2);
  int sum2 = get(tout[cen2]) - get(tin[cen2] - 1);
  if (sum2 == k / 2) {
    return {cen1, cen2};
  } else if (sum1 == k / 2) {
    int cen3 = jump(mid, k / 2 + 1);
    return {cen3, cen1};
  } else if (depth[cen1] < depth[cen2]) {
    return {cen2};
  } else {
    return {cen1};
  }
}

ll segt[4 * N], lazy[4 * N], mn[4 * N];
ll cur = 0;

void build(int v, int tl, int tr) {
  if (tl == tr) {
    int x = who[tl];
    ll aux = distance(centroid[0], x);
    cur += aux;
    if ((int) centroid.size() == 2) {
      aux = max(aux, distance(centroid[1], x));
    }
    segt[v] = lazy[v] = aux;
    mn[v] = tl;
    return;
  }
  int tm = (tl + tr) / 2;
  build(2 * v, tl, tm);
  build(2 * v + 1, tm + 1, tr);
  segt[v] = min(segt[2 * v], segt[2 * v + 1]);
  if (segt[2 * v] <= segt[2 * v + 1]) {
    mn[v] = mn[2 * v];
  } else {
    mn[v] = mn[2 * v + 1];
  }
}

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

void apply(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) {
    apply(2 * v, tl, tm, x, min(tm, y), val);
  }
  if (tm + 1 <= y) {
    apply(2 * v + 1, tm + 1, tr, max(x, tm + 1), y, val);
  }
  push(2 * v, tl, tm);
  push(2 * v + 1, tm + 1, tr);
  segt[v] = min(segt[2 * v], segt[2 * v + 1]);
  if (segt[2 * v] <= segt[2 * v + 1]) {
    mn[v] = mn[2 * v];
  } else {
    mn[v] = mn[2 * v + 1];
  }
}

signed main() {
#ifdef ONPC
  freopen ("input.txt", "r", stdin);
#else
  ios::sync_with_stdio(0); cin.tie(0);
#endif // ONPC

  cin >> n;
  for (int i = 1; i < n; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    g[x].push_back({y, z});
    g[y].push_back({x, z});
  }
  {
    dfs(1);
    for (int i = 1; i <= n; i++) {
      tab[0][i] = par[i];
    }
    for (int k = 1; k < K; k++) {
      for (int i = 1; i <= n; i++) {
        tab[k][i] = tab[k - 1][tab[k - 1][i]];
      }
    }
  }

  for (int i = 1; i <= n; i++) {
    add(i, 1);
  }
  centroid = getcentroid(n);
  build(1, 1, n);
  sol[n] = cur;
  for (int i = n - 1; i >= 2; i--) {
    int x = who[mn[1]];
    sol[i] = sol[i + 1] - mn[1];
    apply(1, 1, n, tin[x], tin[x], INF);
    add(tin[x], -1);
    vector<int> c = getcentroid(i);
    if ((int) c.size() == 2) {
      int cc1 = c[0], cc2 = c[1];
      if (depth[cc1] < depth[cc2]) {
        swap(cc1, cc2);
      }
      ll d1 = distance(cc2, centroid[0]);
      ll d2 = distance(cc1, centroid[0]);
      apply(1, 1, n, tin[cc1], tout[cc1], d1 - d2);
      apply(1, 1, n, 1, n, d2);
    } else if ((int) centroid.size() == 2) {
      int cc1 = centroid[0], cc2 = centroid[1];
      if (depth[cc1] < depth[cc2]) {
        swap(cc1, cc2);
      }
      ll d = distance(cc1, cc2);
      if (cc2 == c[0]) {
        apply(1, 1, n, tin[cc1], tout[cc1], d);
        apply(1, 1, n, 1, n, -d);
      } else {
        apply(1, 1, n, tin[cc1], tout[cc1], -d);
      }
    }
    centroid = c;
  }
  for (int i = 2; i <= n; i += 2) {
    cout << sol [i] << " ";
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 21892kb

input:

7
1 3 99
2 3 82
3 4 4
4 5 43
5 6 5
4 7 3

output:

1285 1293 1304 

result:

wrong answer 1st numbers differ - expected: '181', found: '1285'