树剖模板求助
查看原帖
树剖模板求助
230580
Suzt_ilymtics楼主2020/10/25 11:31
/*
Work by: Suzt_ilymics
Knowledge: ??
Time: O(??)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstring>
using namespace std;
const int MAXN = 1e5+5;
int n;
string s;
int a[MAXN];
int dfn[MAXN], pre[MAXN], son[MAXN], fath[MAXN], siz[MAXN], dep[MAXN], top[MAXN];

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

namespace Seg{
	#define lson i << 1
	#define rson i << 1 | 1
	struct Tree{
		int lazy, len, cover, max;
	}tree[MAXN << 2];
	void push_up(int i){
		tree[i].max = max(tree[lson].max, tree[rson].max);
		return ;
	}
	void pushdown(int i){
		if(tree[i].cover >= 0){
			tree[lson].max = tree[i].cover;
			tree[rson].max = tree[i].cover;
			tree[lson].cover = tree[i].cover;
			tree[rson].cover = tree[i].cover;
			tree[i].cover = -1;
			tree[lson].lazy = tree[rson].lazy = 0;
		}
		if(tree[i].lazy){
			tree[lson].lazy += tree[i].lazy;
			tree[rson].lazy += tree[i].lazy;
			tree[lson].max += tree[lson].lazy;
			tree[rson].max += tree[rson].lazy;
			tree[i].lazy = 0;
		}
		return ;
	}
	void build(int i, int l, int r){
		tree[i].lazy = 0, tree[i].cover = -1, tree[i].len = r - l + 1;
		if(l == r){
			tree[i].max = a[pre[l]];
			return ;
		}
		int mid = (l + r) >> 1;
		build(lson, l, mid), build(rson, mid + 1, r);
		push_up(i);
		return ;
	}
	void add(int i, int l, int r, int L, int R, int k){
		if(L <= l && r <= R){
			tree[i].max += k;
			tree[i].lazy += k;
			return ;
		}
		if(l > R && r < L) return ;
		pushdown(i);
		int mid = (l + r) >> 1;
		if(mid >= L) add(lson, l, mid, L, R, k);
		if(mid < R) add(rson, mid + 1, r, L, R, k);
		push_up(i);
		return ;
	}
	void cover(int i, int l, int r, int L, int R, int k){
		if(L <= l && r <= R){
			tree[i].max = k;
			tree[i].cover = k;
			tree[i].lazy = 0;
			return ;
		}
		if(l > R && r < L) return ;
		pushdown(i);
		int mid = (l + r) >> 1;
		if(mid >= L) cover(lson, l, mid, L, R, k);
		if(mid < R) cover(rson, mid + 1, r, L, R, k);
		push_up(i);
		return ;
	}
	int get_max(int i, int l, int r, int L, int R){
		int maxn = -1e9 + 7;
		if(L <= l && r <= R){
			return tree[i].max;
		}
		if(l > R && r < L) return 0;
		pushdown(i);
		int mid = (l + r) >> 1;
		if(mid >= L) maxn = max(maxn, get_max(lson, l, mid, L, R));
		if(mid < R) maxn = max(maxn, get_max(rson, mid + 1, r, L, R));
		push_up(i);
		return maxn;
	}
}

namespace Cut{
	int num_edge = 0, cnt = 0, head[MAXN << 1] = {0};
	struct edge{
		int to, w, nxt;
	}e[MAXN << 1];
	void add(int from, int to, int w){
		e[++num_edge].nxt = head[from];
		e[num_edge].to = to;
		e[num_edge].w = w;
		head[from] = num_edge;
	}
	void dfs(int x, int fa){
		siz[x] = 1, fath[x] = fa, dep[x] = dep[fa] + 1;
		for(int i = head[x]; i; i = e[i].nxt){
			int v = e[i].to;
			if(v == fa) continue;
	 		a[v] = e[i].w;//将边权转移到点上 
			dfs(v, x);
			siz[x] += siz[v];
			if(siz[son[x]] < siz[v]) son[x] = v;
		}
	}
	void dfs2(int x, int tp){
		top[x] = tp, dfn[x] = ++cnt, pre[cnt] = x;
		if(son[x]) dfs2(son[x], tp);
		for(int i = head[x]; i; i = e[i].nxt){
			int v = e[i].to;
			if(v == fath[x] || v == son[x]) continue;
			dfs2(v, v);
		}
	}
	void change(int k, int w){
		int ee = k * 2 - 1;
		int x = e[ee].to, y = e[ee + 1].to;
		if(fath[x] == y) Seg::cover(1, 1, n, dfn[x], dfn[x], w);
		else Seg::cover(1, 1, n, dfn[y], dfn[y], w);
	}
	void change_add(int x, int y, int k){
		while(top[x] != top[y]){
			if(dep[top[x]] < dep[top[y]]) swap(x, y);
			Seg::add(1, 1, n, dfn[top[x]], dfn[x], k);
			x = fath[top[x]];
		}
		if(dep[x] > dep[y]) swap(x, y);
		Seg::add(1, 1, n, dfn[x] + 1, dfn[y], k);
		return ;
	}
	void change_cover(int x, int y, int k){
		while(top[x] != top[y]){
			if(dep[top[x]] < dep[top[y]]) swap(x, y);
			Seg::cover(1, 1, n, dfn[top[x]], dfn[x], k);
			x = fath[top[x]];
		}
		if(dep[x] > dep[y]) swap(x, y);
		Seg::cover(1, 1, n, dfn[x] + 1, dfn[y], k);
		return ;
	}
	int ask(int x, int y){
		int maxn = -1e9 + 7;
		while(top[x] != top[y]){
			if(dep[top[x]] < dep[top[y]]) swap(x, y);
			maxn = max(maxn, Seg::get_max(1, 1, n, dfn[top[x]], dfn[x]));
			x = fath[top[x]];
		}
		if(dep[x] > dep[y]) swap(x, y);
		maxn = max(maxn, Seg::get_max(1, 1, n, dfn[x] + 1, dfn[y]));
		return maxn;
	}
}

signed main()
{
	n = read();
	for(int i = 1, u, v, w; i <= n - 1; ++i){
		u = read(), v = read(), w = read();
		Cut::add(u, v, w),Cut::add(v, u, w);
	}
	
	Cut::dfs(1, 0), Cut::dfs2(1, 1), Seg::build(1, 1, n);
	
	while(1){
		int x, y, w, k;
		cin>>s;
		if(s[1] == 'a'){//max
			x = read(), y = read();
			printf("%d\n", Cut::ask(x, y));
		}
		if(s[1] == 'o'){//cover
			x = read(), y = read(), w = read();
			Cut::change_cover(x, y, w);
		}
		if(s[1] == 'd'){//add
			x = read(), y = read(), k = read();
			Cut::change_add(x, y, k); 
		} 
		if(s[1] == 'h'){//change
			k = read(), w = read(); 
			Cut::change(k, w);
		}
		if(s[1] == 't'){//stop
			return 0;
		}
	}
}

2020/10/25 11:31
加载中...