Mn Zn 刚学树剖,样例对了爆0,求调
查看原帖
Mn Zn 刚学树剖,样例对了爆0,求调
528287
多喝岩浆楼主2023/2/2 20:41
#include<bits/stdc++.h>
#define int long long
#define PP pair <int, int>

using namespace std;

inline int read () {
	int s = 0, f = 1;
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		s = (s << 1) + (s << 3) + (ch ^ 48);
		ch = getchar ();
	}
	return s;
}

const int N = 1e6 + 10;

struct SegmentTree {
	int l, r, Max, lazy_c, lazy_a;
} tree[N * 4];

struct EDGE {
	int next, to, z, id;
} edge[N * 2];

int head[N], cnt, dep[N], tot, id[N], s[N], w[N], fat[N], son[N], tp[N], siz[N], n, b[N];

inline void add (int x, int y, int z, int id) {
	edge[ ++ cnt].next = head[x];
	edge[cnt].to = y;
	edge[cnt].z = z;
	edge[cnt].id = id;
	head[x] = cnt;
}

void dfs (int x, int fa) {
	siz[x] = 1;
	for (int i = head[x]; i; i = edge[i].next) {
		int y = edge[i].to, z = edge[i].z;
		if (y == fa) continue;
		fat[y] = x;
		dep[y] = dep[x] + 1;
		s[y] = z;
		b[edge[i].id] = y;
		dfs (y, x);
		siz[x] += siz[y];
		if (siz[y] > siz[son[x]]) son[x] = y;
	}
}

void dfs1 (int x, int t) {
	id[x] = ++ tot;
	w[tot] = s[x];
	tp[x] = t;
	if (son[x] == 0) return;
	dfs1 (son[x], t);
	for (int i = head[x]; i; i = edge[i].next) {
		int y = edge[i].to;
		if (y == son[x] || y == fat[x]) continue;
		dfs1 (y, y);
	}
}

void build (int p, int l, int r) {
	tree[p].l = l, tree[p].r = r, tree[p].lazy_c = -1;
	if (l == r) {
		tree[p].Max = w[l];
		return;
	}
	int mid = (l + r) >> 1;
	build (p * 2, l, mid);
	build (p * 2 + 1, mid + 1, r);
	tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}

inline void down (int p) {
	if (tree[p].lazy_c != -1) {
		tree[p * 2].Max = tree[p].lazy_c;
		tree[p * 2 + 1].Max = tree[p].lazy_c;
		tree[p * 2].lazy_c = tree[p].lazy_c;
		tree[p * 2 + 1].lazy_c = tree[p].lazy_c;
		tree[p].lazy_c = -1;
		tree[p].lazy_a = 0;
		return;
	}
	if (tree[p].lazy_a != 0) {
		tree[p * 2].Max += tree[p].lazy_a;
		tree[p * 2 + 1].Max += tree[p].lazy_a;
		tree[p * 2].lazy_a += tree[p].lazy_a;		
		tree[p * 2 + 1].lazy_a += tree[p].lazy_a;		
		tree[p].lazy_a = 0;
		return;
	}
}

void change (int p, int x, int z) {
	if (tree[p].l == tree[p].r) {
		tree[p].Max = z;
		return;
	}
	down (p);
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (x <= mid) change (p * 2, x, z);
	else change (p * 2 + 1, x, z);
	tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}

void Change (int p, int l, int r, int z) {
	if (tree[p].l >= l && tree[p].r <= r) {
		tree[p].Max = z;
		tree[p].lazy_c = z;
		tree[p].lazy_a = 0;
		return;
	}
	down (p);
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (l <= mid) Change (p * 2, l, r, z);
	if (mid < r) Change (p * 2 + 1, l, r, z);
	tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}

void Add (int p, int l, int r, int z) {
	if (tree[p].l >= l && tree[p].r <= r) {
		tree[p].Max += z;
		if (tree[p].lazy_c != -1) tree[p].lazy_c += z;
		else tree[p].lazy_a += z;
		return;
	}
	down (p);
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (l <= mid) Add (p * 2, l, r, z);
	if (mid < r) Add (p * 2 + 1, l, r, z);
	tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}

int query (int p, int l, int r) {
	if (tree[p].l >= l && tree[p].r <= r) return tree[p].Max;
	down (p);
	int mid = (tree[p].l + tree[p].r) >> 1, res = -0x3f3f3f3f;
	if (l <= mid) res = max (res, query (p * 2, l, r));
	if (mid < r) res = max (res, query (p * 2 + 1, l, r));
	return res;
}

inline void TreeChange (int x, int y, int z) {
	if (tp[x] != tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
		Change (1, id[tp[x]], id[x], z);
		x = fat[tp[x]];
	}
	if (dep[x] > dep[y]) swap (x, y);
	Change (1, id[x] + 1, id[y], z);
}

inline void TreeAdd (int x, int y, int z) {
	if (tp[x] != tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
		Add (1, id[tp[x]], id[x], z);
		x = fat[tp[x]];
	}
	if (dep[x] > dep[y]) swap (x, y);
	Add (1, id[x] + 1, id[y], z);
}

inline int TreeQuery (int x, int y) {
	int res = -0x3f3f3f3f;
	if (tp[x] != tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
		res = max (res, query (1, id[tp[x]], id[x]));
		x = fat[tp[x]];
	}
	if (dep[x] > dep[y]) swap (x, y);
	res = max (res, query (1, id[x] + 1, id[y]));
	return res; 
}

signed main () {
//	freopen ("P4315_1.in", "r", stdin);
//	freopen ("asdf.out", "w", stdout);
	n = read ();
	for (int i = 1; i < n; i ++ ) {
		int x = read (), y = read (), z = read ();
		add (x, y, z, i);
		add (y, x, z, i);
	}
	dep[1] = 1;
	dfs (1, 0);
	dfs1 (1, 0);
	build (1, 1, n);
	string a;
	cin >> a;
	while (a != "Stop") {
		if (a == "Change") {
			int k = read (), z = read ();
			change (1, id[b[k]], z);
		} 
		else if (a == "Cover") {
			int x = read (), y = read (), z = read ();
			TreeChange (x, y, z);
		}
		else if (a == "Add") {
			int x = read (), y = read (), z = read ();
			TreeAdd (x, y, z);
		}
		else {
			int x = read (), y = read ();
			cout << TreeQuery (x, y) << endl;
		}
		cin >> a;
	} 
	return 0;
}
/*
2
1 2 1
Max 1 2
Cover 1 2 3
Change 1 1
Max 1 2

2
1 2 1
Cover 1 2 2
Max 1 2
Change 1 1
Max 1 2

5
1 2 2
1 3 1
3 4 4
3 5 3
Max 4 2
Cover 5 1 2
Max 5 1 
Add 1 2 1
Max 5 2
Change 3 1
Max 3 1 
*/
2023/2/2 20:41
加载中...