社区讨论
10分--only AC on11
P4315月下“毛景树”参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mk83hfmt
- 此快照首次捕获于
- 2026/01/10 17:20 2 个月前
- 此快照最后确认于
- 2026/01/13 15:25 2 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long n;
vector<long long>graph[N];
long long siz[N], son[N], dep[N], fa[N];
void heavy(long long u, long long Fa, long long Dep) {
siz[u] = 1;
fa[u] = Fa;
dep[u] = Dep;
long long msiz = 0, mid = 0;
for (auto i : graph[u]) {
if (i == Fa)continue;
heavy(i, u, Dep + 1);
if (siz[i] > msiz) {
msiz = siz[i];
mid = i;
}
siz[u] += siz[i];
}
son[u] = mid;
}
long long head[N], dfn[N], rnk[N], cnt = 0;
void dfs(long long u, long long Fa, long long Head) {
head[u] = Head;
dfn[u] = ++cnt;
rnk[cnt] = u;
if (son[u])dfs(son[u], u, Head);
for (auto i : graph[u]) {
if (i == Fa || i == son[u])continue;
dfs(i, u, i);
}
}
long long tree[N * 4];
long long tag[N * 4];
long long tag1[N * 4];
map<pair<long long, long long>, long long>mp;
void build(long long id, long long l, long long r) {
if (l == r) {
tree[id] = mp[ {rnk[l], fa[rnk[l]]}];
return ;
}
long long mid = (l + r) >> 1;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
tree[id] = max(tree[id * 2], tree[id * 2 + 1]);
}
void pushdown(long long id, long long l, long long r) {
if (tag[id] != -1) {
long long mid = (l + r) >> 1;
tree[id * 2] = (mid - l + 1) * tag[id];
tree[id * 2 + 1] = (r - mid) * tag[id];
tag[id * 2] = tag[id];
tag1[id * 2] = 0;
tag[id * 2 + 1] = tag[id];
tag1[id * 2 + 1] = 0;
tag[id] = -1;
}
if (tag1[id]) {
long long mid = (l + r) >> 1;
tree[id * 2] += (mid - l + 1) * tag1[id];
tree[id * 2 + 1] += (r - mid) * tag1[id];
tag1[id * 2] += tag1[id];
tag1[id * 2 + 1] += tag1[id];
tag1[id] = 0;
}
}
void up(long long id, long long l, long long r, long long ql, long long qr, long long val) {
if (ql <= l && r <= qr) {
tag[id] = val;
tag1[id] = 0;
tree[id] = val;
return ;
}
pushdown(id, l, r);
long long mid = (l + r) >> 1;
if (ql <= mid)up(id * 2, l, mid, ql, qr, val);
if (qr > mid)up(id * 2 + 1, mid + 1, r, ql, qr, val);
tree[id] = max(tree[id * 2 + 1], tree[id * 2]);
}
void up1(long long id, long long l, long long r, long long ql, long long qr, long long val) {
if (ql <= l && r <= qr) {
tree[id] += val;
tag1[id] += val;
return ;
}
pushdown(id, l, r);
long long mid = (l + r) >> 1;
if (ql <= mid)up1(id * 2, l, mid, ql, qr, val);
if (qr > mid)up1(id * 2 + 1, mid + 1, r, ql, qr, val);
tree[id] = max(tree[id * 2 + 1], tree[id * 2]);
}
void upchain(long long x, long long y, long long z) {
while (head[x] != head[y]) {
if (dep[head[x]] < dep[head[y]]) {
swap(x, y);
}
up(1, 1, n, dfn[head[x]], dfn[x], z);
x = fa[head[x]];
}
if (dep[x] > dep[y]) {
swap(x, y);
}
up(1, 1, n, dfn[x] + 1, dfn[y], z);
}
void upchain1(long long x, long long y, long long z) {
while (head[x] != head[y]) {
if (dep[head[x]] < dep[head[y]]) {
swap(x, y);
}
up1(1, 1, n, dfn[head[x]], dfn[x], z);
x = fa[head[x]];
}
if (dep[x] > dep[y]) {
swap(x, y);
}
up1(1, 1, n, dfn[x] + 1, dfn[y], z);
}
long long query(long long id, long long l, long long r, long long ql, long long qr) {
if (ql <= l && r <= qr) {
return tree[id];
}
pushdown(id, l, r);
long long mid = (l + r) >> 1;
long long ans = 0;
if (ql <= mid)ans = max(ans, query(id * 2, l, mid, ql, qr));
if (qr > mid)ans = max(ans, query(id * 2 + 1, mid + 1, r, ql, qr));
return ans;
}
long long querychain(long long x, long long y) {
long long ans = 0;
while (head[x] != head[y]) {
if (dep[head[x]] < dep[head[y]]) {
swap(x, y);
}
ans = max(ans, query(1, 1, n, dfn[head[x]], dfn[x]));
x = fa[head[x]];
}
if (dep[x] > dep[y]) {
swap(x, y);
}
ans = max(ans, query(1, 1, n, dfn[x] + 1, dfn[y]));
return ans;
}
vector<pair<long long, long long>>side;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
for (long long i = 1; i <= N * 4; i++) {
tag[i] = -1;
}
cin >> n;
for (long long i = 1; i < n; i++) {
long long u, v, w;
cin >> u >> v >> w;
graph[u].push_back(v);
graph[v].push_back(u);
mp[ {u, v}] = w;
mp[ {v, u}] = w;
side.push_back({u, v});
}
heavy(1, 0, 1);
dfs(1, 0, 1);
build(1, 1, n);
string op;
while (cin >> op) {
if (op == "Stop")break;
long long x, y;
cin >> x >> y;
if (op == "Change") {
long long a = side[x - 1].first, b = side[x - 1].second;
if (fa[a] == b) {
swap(a, b);
}
up(1, 1, n, fa[dfn[b]], dfn[b], y);
} else if (op == "Cover") {
long long z;
cin >> z;
upchain(x, y, z);
} else if (op == "Add") {
long long z;
cin >> z;
upchain1(x, y, z);
} else {
cout << querychain(x, y) << '\n';
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...