帮帮我吧
查看原帖
帮帮我吧
632955
伊地知虹夏楼主2024/5/30 23:19

部分测试点 Wa,按照第 2 篇题解的思路写的。

#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int N = 2e5 + 5;
#define _for(i, l, r) for (int i = l; i <= r; i++)
typedef long long ll;
ll ans;
int n, cnt, V;
int in[N], a[N], h[N], c[N], bel[N], rt[N], nt[N], b[N];
ll v[N << 6], tg[N << 6];
int tot, ls[N << 6], rs[N << 6];
void adtg(int x, ll val) {
  if (x) v[x] += val, tg[x] += val;
}
void up(int x) { v[x] = min(v[ls[x]], v[rs[x]]); }
void dn(int x) {
  if (!tg[x]) return;
  adtg(ls[x], tg[x]), adtg(rs[x], tg[x]), tg[x] = 0;
}
void Modify(int &c, int x, ll val, int l = 1, int r = V) {
  if (!c) c = ++tot;
  if (l == r) {
    v[c] = val;
    return;
  }
  int mid = l + r >> 1;
  dn(c);
  if (x <= mid)
    Modify(ls[c], x, val, l, mid);
  else
    Modify(rs[c], x, val, mid + 1, r);
  up(c);
}
ll Query(int c, int x, int y, int l = 1, int r = V) {
  if (!c) return 0;
  if (x <= l && r <= y) return v[c];
  int mid = l + r >> 1;
  ll res = 0;
  if (x <= mid) res = min(res, Query(ls[c], x, y, l, mid));
  if (mid < y) res = min(res, Query(rs[c], x, y, mid + 1, r));
  return res;
}
ll Ml, Mr;
int mrg(int x, int y, int l = 1, int r = V) {
  if (!x && !y) return 0;
  if (!y) {
    Ml = min(Ml, v[x]), adtg(x, Mr);
    return x;
  }
  if (!x) {
    Mr = min(Mr, v[y]), adtg(y, Ml);
    return y;
  }
  if (l == r) {
    Ml = min(Ml, v[x]), Mr = min(Mr, v[y]);
    v[x] += Mr, v[y] += Ml, v[x] = min(v[x],v[y]);
    return x;
  }
  int mid = l + r >> 1;
  dn(x), dn(y);
  rs[x] = mrg(rs[x], rs[y], mid + 1, r);
  ls[x] = mrg(ls[x], ls[y], l, mid), up(x);
  return x;
}
vector<int> G[N];
vector<pair<int, int> > l[N];
void Mrg(int &x, int y) {
  Ml = Mr = 0, x = mrg(x, y);
}

void dp(int x){
  for(auto y:G[x]) dp(y), Mrg(rt[x],rt[y]);
  Modify(rt[x],h[x],Query(rt[x],h[x],V) - c[x]);
}

void Get(int x) {
  bel[x] = cnt;
  l[cnt].push_back({h[x], c[x]});
  if (!bel[a[x]]) Get(a[x]);
}
void Topo() {
  queue<int> q;
  for (int i = 1; i <= n; i++)
    if (!in[i]) q.push(i);
  for (int x; !q.empty();) {
    x = q.front(); q.pop();
    if (--in[a[x]] == 0) q.push(a[x]);
  }
  _for(i, 1, n) if (!bel[i] && in[i]) ++ cnt, Get(i);
}
void Solve() {
  _for(i, 1, n) if (!in[i] && in[a[i]]) {
    dp(i), Mrg(nt[bel[a[i]]], rt[i]);
  }
  _for(i, 1, cnt) {
    sort(l[i].begin(), l[i].end());
    ll res = v[nt[i]], nh = 0, sc = 0;
    for (auto t : l[i]) {
      int x = t.first,y = t.second;
      if (nh == 0) {
        nh = x, sc = y;
        continue;
      }
      if (x == nh) sc += y;
      else {
        res = min(res, Query(nt[i], nh, V) - sc);
        nh = x, sc = y;
      }
    }
    res = min(res, Query(nt[i], nh, V) - sc);
    ans += res;
  }
}
signed main() {
  cin >> n;
  _for(i, 1, n) cin >> a[i] >> h[i] >> c[i];
  _for(i, 1, n){
    G[a[i]].push_back(i);
    b[i] = h[i], ++ in[a[i]];
    ans += c[i];
  }
  sort(b + 1, b + 1 + n);
  V = unique(b + 1, b + 1 + n) - b - 1;
  _for(i, 1, n) h[i] = lower_bound(b + 1, b + 1 + V, h[i]) - b;
  Topo(), Solve();
  cout << ans;
  return 0;
}
2024/5/30 23:19
加载中...