社区讨论
玄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 条回复,欢迎继续交流。
正在加载回复...