社区讨论

玄5RMB(需要有微信+小号关,25pts求条QwQ

P4069[SDOI2016] 游戏参与者 4已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mlhok1ij
此快照首次捕获于
2026/02/11 15:00
上周
此快照最后确认于
2026/02/11 15:40
上周
查看原帖
CPP
#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll N = 3e5 + 5, INF = 123456789123456789;

struct S {
  ll x, w;
};

vector<S> v[N];

ll n, m, p[N * 8], dep[N], siz[N], son[N], dis[N], dfn[N], a[N], tot, lietot = 1, id[N], cnt[N], f[N], dp[N][22], tr[N * 8];

void Dfs(ll x, ll fa) {
  dep[x] = dep[fa] + 1;
  siz[x] = 1, f[x] = dp[x][0] = fa;
  for (ll i = 0; i < v[x].size(); i++) {
    ll nx = v[x][i].x, w = v[x][i].w;
    if (nx == fa) {
      continue;
    }
    dis[nx] = dis[x] + w;
    Dfs(nx, x);
    siz[x] += siz[nx];
    if (siz[nx] > siz[son[x]]) {
      son[x] = nx;
    }
  }
}

void init() {
  for (ll j = 1; j <= 20; j++) {
    for (ll i = 1; i <= n; i++) {
      dp[i][j] = dp[dp[i][j - 1]][j - 1];
    }
  }
}

ll LCA(ll x, ll y) {
  if (dep[x] < dep[y]) {
    swap(x, y);
  }
  for (ll i = 0; i <= 20; i++) {
    if (((dep[x] - dep[y]) >> i) & 1) {
      x = dp[x][i];
    }
  }
  for (ll i = 20; i >= 0; i--) {
    if (dp[x][i] != dp[y][i]) {
      x = dp[x][i], y = dp[y][i];
    }
  }
  return (x == y ? x : dp[x][0]);
}

void get_dfs(ll x, ll fa, ll o) {
  cnt[x] = o, id[x] = ++tot;
  dfn[tot] = x;
  if (son[x]) {
    get_dfs(son[x], x, o);
  }
  for (ll i = 0; i < v[x].size(); i++) {
    ll nx = v[x][i].x;
    if (nx == fa || nx == son[x]) {
      continue;
    }
    get_dfs(nx, x, nx);
  }
}

struct Line {
  ll k, b;
} lie[N];

ll calc(ll x, ll id) {
  return (dis[dfn[x]] * lie[id].k) + lie[id].b;
}

void pushup(ll x, ll l, ll r) {
  tr[x] = min(min(calc(l, p[x]), calc(r, p[x])), min(tr[2 * x], tr[2 * x + 1]));
}

void update(ll x, ll l, ll r, ll sx, ll ex, ll num) {
  ll mid = (l + r) / 2;
  if (l == sx && r == ex) {
    if (calc(mid, p[x]) > calc(mid, num)) {
      swap(p[x], num);
    }
    if (l == r) {
      tr[x] = min(calc(l, p[x]), calc(r, p[x]));
      return;
    }
    if (calc(l, p[x]) <= calc(l, num) && calc(r, p[x]) <= calc(r, num)) {
      return;  
    }
    if (calc(l, p[x]) <= calc(l, num)) {
      update(2 * x + 1, mid + 1, r, mid + 1, r, num);
    } else {
      update(2 * x, l, mid, l, mid, num);
    }
    pushup(x, l, r);
    return;
  }
  if (sx <= mid) {
    update(2 * x, l, mid, sx, min(ex, mid), num);
  }
  if (mid + 1 <= ex) {
    update(2 * x + 1, mid + 1, r, max(sx, mid + 1), ex, num);
  }
  pushup(x, l, r);
}

ll query(ll x, ll l, ll r, ll sx, ll ex) {
  if (l == sx && r == ex) {
    return tr[x];
  }
  ll mid = (l + r) / 2, ans = min(calc(max(l, sx), p[x]), calc(min(ex, r), p[x]));
  if (sx <= mid) {
    ans = min(ans, query(2 * x, l, mid, sx, min(ex, mid)));
  }
  if (mid + 1 <= ex) {
    ans = min(ans, query(2 * x + 1, mid + 1, r, max(sx, mid + 1), ex));
  }
  return ans;
}

void add(ll x, ll y, ll num) {
  for (; cnt[x] != cnt[y]; x = f[cnt[x]]) {
    update(1, 1, n, id[cnt[x]], id[x], num);
  }
  update(1, 1, n, id[y], id[x], num);
}

ll Ans(ll x, ll y) {
  ll ans = INF;
  for (; cnt[x] != cnt[y]; x = f[cnt[x]]) {
    ans = min(ans, query(1, 1, n, id[cnt[x]], id[x]));
  }
  return min(ans, query(1, 1, n, id[y], id[x]));
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n >> m;
  lie[1] = {0ll, (ll)INF};
  for (ll x, y, w, i = 1; i < n; i++) {
    cin >> x >> y >> w;
    v[x].push_back({y, w}), v[y].push_back({x, w});
  }
  Dfs(1, 0), get_dfs(1, 0, 1);
  init();
  for (int i = 1; i <= (n * 8); i++) {
    p[i] = 1, tr[i] = INF;
  }
  for (ll op, s, t, k, b; m--;) {
    cin >> op;
    if (op == 1) {
      cin >> s >> t >> k >> b;
      ll cnt = LCA(s, t);
      lie[++lietot] = {-k, b + (k * dis[s])};
      add(s, cnt, lietot);
      ll tmp = k * (dis[s] - dis[cnt]);
      lie[++lietot] = {k, b + tmp - (k * dis[cnt])};
      add(t, cnt, lietot);
    } else {
      cin >> s >> t;
      ll cnt = LCA(s, t);
      cout << min(Ans(s, cnt), Ans(t, cnt)) << "\n";
    }
  }
  return 0;
}
https://www.luogu.com.cn/record/262219562

回复

6 条回复,欢迎继续交流。

正在加载回复...