社区讨论
萌新求助o(╥﹏╥)o, 树剖调了3个小时,样例过了,全WA
P4315月下“毛景树”参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo2c912q
- 此快照首次捕获于
- 2023/10/23 11:28 2 年前
- 此快照最后确认于
- 2023/11/03 11:37 2 年前
C
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MAX = 2e5 + 70;
int n, tot, num, bel[MAX], dfn[MAX], nfd[MAX], val[MAX], head[MAX], dep[MAX], siz[MAX], f[MAX], id_e[MAX];
struct made {
int l, t, val, id;
}edge[MAX * 2];
void add(int u, int v, int val, int id) {
edge[++tot].l = head[u];
edge[tot].t = v;
edge[tot].val = val;
edge[tot].id = id;
head[u] = tot;
}
struct SegmentTree {
int l, r, val, data, dato;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define val(x) tree[x].val
#define data(x) tree[x].data
#define dato(x) tree[x].dato
}tree[MAX * 4];
char ch[50];
void dfs_size(int x, int fa, int id) {
dep[x] = dep[fa] + 1, siz[x] = 1; f[x] = fa, id_e[id] = x;
for(int i = head[x]; i; i = edge[i].l) {
int t = edge[i].t;
if(t == fa) continue;
val[t] = edge[i].val;
dfs_size(t, x, edge[i].id);
siz[x] += siz[t];
}
}
void dfs(int p, int chain) {
int k = 0; dfn[p] = ++num, nfd[num] = p, bel[p] = chain;
for(int i = head[p]; i; i = edge[i].l) {
int t = edge[i].t;
if(dep[t] == dep[p] + 1) if(siz[t] > siz[k]) k = t;
}
if(k != 0) dfs(k, chain);
for(int i = head[p]; i; i = edge[i].l) {
int t = edge[i].t;
if(dep[t] == dep[p] + 1 && t != k) dfs(t, t);
}
}
void build(int p, int l, int r) {
l(p) = l; r(p) = r; dato(p) = -1; data(p) = 0;
if(l(p) == r(p)) {
val(p) = val[nfd[l(p)]];
// printf("val(%d) %d l(%d) %d r(%d) %d\n", p, val(p), p, l(p), p, r(p));
return ;
}
int mid = (l + r) / 2;
build(2 * p, l, mid);
build(2 * p + 1, mid + 1, r);
val(p) = max(val(2 * p), val(2 * p + 1));
// printf("val(%d) %d l(%d) %d r(%d) %d\n", p, val(p), p, l(p), p, r(p));
}
void spread_add(int p) {
if(data(p) != 0) {
if(data(2 * p) != 0) { data(2 * p) += data(p); val(2 * p) += data(p); }
else { dato(2 * p) += data(p); val(2 * p) += data(p); }
if(data(2 * p + 1) != 0) { data(2 * p + 1) += data(p); val(2 * p + 1) += data(p); }
else { dato(2 * p + 1) += data(p); val(2 * p + 1) += data(p); }
data(p) = 0;
}
}
void spread_change(int p) {
if(dato(p) != -1) {
dato(2 * p) = dato(p); val(2 * p) = dato(p);
dato(2 * p + 1) = dato(p); val(2 * p + 1) = dato(p);
data(2 * p) = data(2 * p + 1) = data(p) = 0;
dato(p) = -1;
}
}
void change(int p, int l, int r, int w) {
if(l(p) >= l && r(p) <= r) { dato(p) = val(p) = w; data(p) = 0; return ; }
spread_change(p); spread_add(p); int mid = (l(p) + r(p)) / 2;
if(mid >= r) change(2 * p, l, r, w);
else if(mid < l) change(2 * p + 1, l, r, w);
else { change(2 * p, l, r, w); change(2 * p + 1, l, r, w); }
val(p) = max(val(2 * p), val(2 * p + 1));
}
void modify(int p, int l, int r, int w) {
if(l(p) >= l && r(p) <= r) {
if(dato(p) != -1) dato(p) += w;
else data(p) += w;
val(p) += w;
return ;
}
spread_change(p); spread_add(p); int mid = (l(p) + r(p)) / 2;
if(mid >= r) modify(2 * p, l, r, w);
else if(mid < l ) modify(2 * p + 1, l, r, w);
else { modify(2 * p, l, r, w); modify(2 * p + 1, l, r, w); }
val(p) = max(val(2 * p), val(2 * p + 1));
}
int find(int p, int l, int r) {
int maxx = 0, mid;
if(l(p) >= l && r(p) <= r) return val(p);
spread_change(p); spread_add(p); mid = (l(p) + r(p)) / 2;
if(mid >= r) maxx = max(maxx, find(2 * p, l, r));
else if(mid < l) maxx = max(maxx, find(2 * p + 1, l, r));
else { maxx = max(maxx, find(2 * p, l, r)); maxx = max(maxx, find(2 * p + 1, l, r)); }
return maxx;
}
int lca(int u, int v) {
while(bel[u] != bel[v]) {
dep[bel[u]] < dep[bel[v]] ? v = f[bel[v]] : u = f[bel[u]];
}
return dep[u] < dep[v] ? u : v;
}
void Q_change(int u, int v, int w, int id) {
if(id == 1) {
int Top = lca(u, v);
// printf("u %d v %d Top %d\n",u, v, Top);
while(bel[u] != bel[Top]) { change(1, dfn[bel[u]], dfn[u], w); u = f[bel[u]]; }
while(bel[v] != bel[Top]) { change(1, dfn[bel[v]], dfn[v], w); v = f[bel[v]]; }
int l = (dep[u] < dep[v] ? u : v), r = (dep[u] < dep[v] ? v : u);
// printf("l %d r %d\n", l, r);
if(dfn[l] != dfn[r]) change(1, dfn[l] + 1, dfn[r], w);
}
else { change(1, dfn[u], dfn[v], w);}
// printf("&&&\n");
}
int Q_find(int u, int v) {
int Top = lca(u, v), ans = 0;
while(bel[u] != bel[Top]) { ans = max(find(1, dfn[bel[u]], dfn[u]), ans); u = f[bel[u]]; }
while(bel[v] != bel[Top]) { ans = max(find(1, dfn[bel[v]], dfn[v]), ans); v = f[bel[v]]; }
if(dep[u] > dep[v]) swap(u, v);
if(dfn[u] != dfn[v]) ans = max(ans, find(1, dfn[u] + 1, dfn[v]));
return ans;
}
void Q_modify(int u, int v, int w) {
int Top = lca(u, v);
while(bel[u] != bel[Top]) { modify(1, dfn[bel[u]], dfn[u], w); u = f[bel[u]]; }
while(bel[v] != bel[Top]) { modify(1, dfn[bel[v]], dfn[v], w); v = f[bel[v]]; }
if(dep[u] > dep[v]) swap(u, v);
if(dfn[u] != dfn[v]) modify(1, dfn[u] + 1, dfn[v], w);
}
int main() {
// freopen("test.in","r",stdin);
// freopen("data.out","w",stdout);
scanf("%d", &n);
for(int i = 1; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w, i);
add(v, u, w, i);
}
dfs_size(1, 0, 0);
dfs(1, 1);
build(1, 1, n);
while(~scanf("%s", ch + 1), ch[1] != 'S') {
int u, v, w;
if(ch[1] == 'M') {
scanf("%d%d", &u, &v);
// printf("dfn[%d] %d dfn[%d] %d\n", u, dfn[u], v, dfn[v]);
int ans = Q_find(u, v);
printf("%d\n", ans);
}
else if(ch[1] == 'C' && ch[2] == 'h') {
scanf("%d%d", &u, &v);
// printf("change id_u[] %d v %d\n", id_e[u], v);
Q_change(id_e[u], id_e[u], v, 0);
}
else if(ch[1] == 'A') {
scanf("%d%d%d", &u, &v, &w);
Q_modify(u, v, w);
}
else if(ch[1] == 'C' && ch[2] == 'o') {
scanf("%d%d%d", &u, &v, &w);
Q_change(u, v, w, 1);
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...