萌新求调树剖
查看原帖
萌新求调树剖
552376
sixrc楼主2022/2/21 22:20

RT,应该写得够清楚了,样例第一个输出 0 第二个没错,麻烦大佬帮忙调一下,谢谢

#include <bits/stdc++.h>
using namespace std;
#define lc(x) x<<1
#define rc(x) x<<1|1
int n, p, x, y, z, w[100010], h[200010]; string st;
int f[100010], dfn[100010], dep[100010], siz[100010], top[100010], son[100010], rnk[100010];
struct node{
	int x, y, z, next;
}a[200010];
void add(int x, int y, int z){
	a[++p].x = x, a[p].y = y, a[p].z = z, a[p].next = h[x], h[x] = p;
}
void dfs1(int x, int fa){
	f[x] = fa, dep[x] = dep[fa] + 1, siz[x] = 1;
	for (int i=h[x]; i; i=a[i].next){
		int y = a[i].y, val = a[i].z;
		if (y == fa) continue;
		w[y] = val;
		dfs1(y, x);
		siz[x] += siz[y];
		if (siz[y] > siz[son[x]]) son[x] = y;
	}
}
void dfs2(int x, int tp){
	dfn[x] = ++dfn[0];
	top[x] = tp;
	rnk[dfn[0]] = w[x];
	if (!son[x]) return ;
	dfs2(son[x], tp);
	for (int i=h[x]; i; i=a[i].next){
		int y = a[i].y;
		if (y == f[x] || y == son[x]) continue;
		dfs2(y, y);
	}
}

int d[400010], tag[400010], cg[400010];
void pushup(int k){
	d[k] = max(d[lc(k)], d[rc(k)]);
}
void pushdown(int k){
	if (cg[k] != -1){
		cg[lc(k)] = cg[rc(k)] = d[lc(k)] = d[rc(k)] = cg[k];
		tag[lc(k)] = tag[rc(k)] = 0;
		cg[k] = -1;
	}
	if (tag[k]){
		tag[lc(k)] += tag[k];
		tag[rc(k)] += tag[k];
		d[lc(k)] += tag[k];
		d[rc(k)] += tag[k];
		tag[k] = 0;
	}
}
void build(int k, int l, int r){
	if (l == r){
		d[l] = w[l];
		return ;
	}
	int mid = l + r >> 1;
	build(lc(k), l, mid);
	build(rc(k), mid+1, r);
	pushup(k);
}
void change(int k, int l, int r, int x, int y, int p){
	if (x <= l && r <= y){
		d[k] = p, cg[k] = p, tag[k] = 0;
		return ;
	}
	pushdown(k);
	int mid = l + r >> 1;
	if (x <= mid) change(lc(k), l, mid, x, y, p);
	if (y > mid) change(rc(k), mid+1, r, x, y, p);
	pushup(k);
}
void add(int k, int l, int r, int x, int y, int p){
	if (x <= l && r <= y){
		d[k] += p, tag[k] += p;
		return ;
	}
	pushdown(k);
	int mid = l + r >> 1;
	if (x <= mid) change(lc(k), l, mid, x, y, p);
	if (y > mid) change(rc(k), mid+1, r, x, y, p);
	pushup(k);
}
int query(int k, int l, int r, int x, int y){
	if (x <= l && r <= y) return d[k];
	pushdown(k);
	int mid = l + r >> 1, ret = -1e9-7;
	if (x <= mid) ret = max(ret, query(lc(k), l, mid, x, y));
	if (y > mid) ret = max(ret, query(rc(k), mid+1, r, x, y));
	return ret;
}
void changeT(int x, int y, int z){
	while (top[x] != top[y]){
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		change(1, 1, n, dfn[top[x]], dfn[x], z);
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	change(1, 1, n, dfn[x]+1, dfn[y], z);//dfn[x]+1即是边权转化为点权 
}
void addT(int x, int y, int z){
	while (top[x] != top[y]){
		if (dep[top[x]] < dep[top[y]]) swap (x, y);
		add(1, 1, n, dfn[top[x]], dfn[x], z);
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	add(1, 1, n, dfn[x]+1, dfn[y], z);
}
int queryT(int x, int y){
	int res = -1e9 - 7;
	while (top[x] != top[y]){
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		res = max(res, query(1, 1, n, dfn[top[x]], dfn[x]));
		x = f[top[x]];
	}
	if (dfn[x] > dfn[y]) swap(x, y);
	return res = max(res, query(1, 1, n, dfn[x]+1, dfn[y]));
}
int main(){
	memset(cg, -1, sizeof(cg));
	scanf ("%d", &n);
	for (int i=1; i<n; i++){
		scanf ("%d%d%d", &x, &y, &z);
		add(x, y, z); add(y, x, z);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	while (cin >> st){
		if (st == "Stop") return 0;
		if (st == "Max"){
			scanf ("%d%d", &x, &y);
			printf ("%d\n", queryT(x, y));
		}
		else if (st == "Add"){
			scanf ("%d%d%d", &x, &y, &z);
			addT(x, y, z);
		}
		else if (st == "Cover"){
			scanf ("%d%d%d", &x, &y, &z);
			changeT(x, y, z);
		}
		else{
			scanf ("%d%d", &x, &z);
			int X = a[x*2].x, Y = a[x*2].y;
			if (dep[X] > dep[Y]) swap(X, Y);
			changeT(X, Y, z);
		}
	}
	return 0;
}
2022/2/21 22:20
加载中...