P4315 月下“毛景树”

P4315 月下“毛景树”

月下“毛景坑”,调试了几个小时,终于过了
线段树,真的牛(永远的坑

坑很多,都是些注意点,希望同样踩坑的朋友能在这里找到答案

注意点
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
//存图
int cnt,h[N], to[N*2], w[N*2], ne[N*2];
void add(int a, int b, int c) {
	to[++cnt] = b;
	w[cnt] = c;
	ne[cnt] = h[a];
	h[a] = cnt;
}
//树链
int dep[N], sz[N], son[N], fa[N],a[N];
void dfs1(int u, int father) {
	fa[u] = father; dep[u] = dep[father] + 1;
	sz[u] = 1;
	for (int i = h[u]; i; i = ne[i]) {
		int v = to[i];
		if (v == father) continue;
		a[v] = w[i];
		dfs1(v, u);
		sz[u] += sz[v];
		if (sz[son[u]] < sz[v]) son[u] = v;
	}
}
int top[N], id[N], tt, nw[N];
void dfs2(int u, int t) {
	top[u] = t; id[u] = ++tt; nw[tt] = a[u];
	if (!son[u])return;
	dfs2(son[u], t);
	for (int i = h[u]; i; i = ne[i]) {
		int v = to[i];
		if (v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}
//线段树
#define lc k<<1
#define rc k<<1|1
struct tree {
	int l, r;
	int sum, lz;
	int cov;
}tr[4*N];
void pushup(int k) {
	tr[k].sum = max(tr[lc].sum , tr[rc].sum);//注意求最大
}
void pushdown(int k) {
	if (~tr[k].cov) {
		tr[lc].sum =  tr[k].cov;//求最大,直接赋值就好
		tr[rc].sum =  tr[k].cov;
		tr[lc].cov = tr[k].cov;
		tr[rc].lz=tr[lc].lz = 0;//注意改为0
		tr[rc].cov = tr[k].cov;
		tr[k].cov = -1;//注意修改
	}
	if (tr[k].lz) {
		tr[lc].sum += tr[k].lz;
		tr[rc].sum += tr[k].lz;
		tr[lc].lz += tr[k].lz;
		tr[rc].lz += tr[k].lz;
		tr[k].lz=0;
	}
}
//建树
void build(int k, int l, int r) {
	tr[k] = { l,r ,0,0,-1};
	if (l == r) {
		tr[k].sum = nw[l];
		return;
	}
	int mid = l + r >> 1;
	build(lc, l, mid); build(rc, mid + 1, r);
	pushup(k);
}
//区间查询
int query(int k, int l, int r) {
	if (tr[k].l >= l && tr[k].r <= r) return tr[k].sum;
	pushdown(k);
	int ans = 0;
	int mid = tr[k].l + tr[k].r >> 1;
	if (l <= mid) ans =max( query(lc, l, r),ans);
	if (r > mid) ans =max( query(rc, l, r),ans);
	return ans;
}
int query_path(int u, int v) {
	int ans = 0;
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		ans = max(query(1, id[top[u]], id[u]),ans);
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) swap(u, v);
	ans =max( query(1, id[v]+1, id[u]),ans);
	return ans;
}
//区间加
void modify_add(int k, int l, int r,int z) {
	if (tr[k].l >= l && tr[k].r <= r) {
		tr[k].sum +=  z;
		tr[k].lz += z;
		return;
	}
	pushdown(k);
	int mid = tr[k].l + tr[k].r >> 1;
	if (l <= mid) modify_add(lc, l, r,z);
	if (r > mid) modify_add(rc, l, r,z);
	pushup(k);
}
void Add(int u, int v, int z) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		modify_add(1, id[top[u]], id[u],z);
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) swap(u, v);
	modify_add(1, id[v]+1, id[u],z);//注意id[v]+1,选它的儿子
}
//单点修改
void change(int k, int x, int z) {
	if (tr[k].l == x && tr[k].r == x) {
		tr[k].sum =z;
		return;
	}
	pushdown(k);
	int mid = tr[k].l + tr[k].r >> 1;
	if (x <= mid) change(lc, x,z);
	else if (x > mid) change(rc, x,z);
	pushup(k);
}
//区间覆盖
void modify_cov(int k, int l, int r, int z) {
	if (tr[k].l >= l && tr[k].r <= r) {
		tr[k].cov = z;
		tr[k].sum = z;
		tr[k].lz = 0;//注意,要改为0
		return;
	}
	pushdown(k);
	int mid = tr[k].l + tr[k].r >> 1;
	if (l <= mid) modify_cov(lc, l, r, z);
	if (r > mid) modify_cov(rc, l, r, z);
	pushup(k);
}
void Cover(int u, int v, int z) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		modify_cov(1, id[top[u]], id[u], z);
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) swap(u, v);
		modify_cov(1, id[v]+1, id[u], z);
}
int main() {

	int n;
	cin >> n;
	for (int i = 1; i < n; i++) {
		int x, y,z;
		cin >> x >> y>>z;
		add(x, y, z);
		add(y, x, z);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	string s;
	while (cin >> s) {
		if (s == "Stop") break;
		if (s == "Max") {
			int x, y;
			cin >> x >> y;
			cout << query_path(x,y) << '\n';
		}
		else if(s=="Cover") {
			int x, y, z;
			cin >> x >> y >> z;
			Cover(x, y,z);
		}
		else if (s == "Add") {
			int x, y, z;
			cin >> x >> y >> z;
			Add(x, y, z);
		}
		else {
			int x, z;
			cin >> x >> z;
			x = dep[to[x << 1]] < dep[to[x*2 - 1]] ? to[x *2 - 1] : to[x << 1];//深度更深的为要改的点
			change(1,id[x], z);
		}
	}
	return 0;
}
posted @ 2023-09-26 09:31  不o凡  阅读(34)  评论(0)    收藏  举报