社区讨论

萌新求助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 条回复,欢迎继续交流。

正在加载回复...