MnZn 刚学 OI,20 pts 求调
查看原帖
MnZn 刚学 OI,20 pts 求调
246099
dalao_see_me楼主2021/10/18 13:46

Rt,过了 11 和 12。

#include <bits/stdc++.h>
#define int long long
#define lx x << 1
#define rx x << 1 | 1 
using namespace std;
const int N = 2e5 + 5;
struct edge {
	int to, nxt, val;
} e[N << 1];
struct Node {
	int u, v;
} E[N];
struct Segment_tree {
	int l, r, sum, lazy, mx, mn;
} t[N << 2];
int lst[N], siz[N], son[N], dfn[N], Top[N], f[N], dep[N], w[N], a[N];
int n, cnt, q, tot;
inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -f; c = getchar();}
	while (c >= '0' && c <= '9') {x = x * 10 + (c ^ 48); c = getchar();}
	return x * f;
}
inline void add(int u, int v, int w) {
	e[++cnt].to = v;
	e[cnt].nxt = lst[u];
	e[cnt].val = w;
	lst[u] = cnt;
}
inline void pushup(int x) {
	t[x].sum = t[lx].sum + t[rx].sum;
	t[x].mx = max(t[lx].mx, t[rx].mx);
	t[x].mn = min(t[lx].mn, t[rx].mn);
}
inline void build(int x, int l, int r) {
	t[x].l = l; t[x].r = r; t[x].lazy = 0;
	if (l == r) {
		t[x].sum = t[x].mx = t[x].mn = w[l];
		return;
	}
	int mid = l + r >> 1;
	build(lx, l, mid); build(rx, mid + 1, r);
	pushup(x); 
}
inline void pushdown(int x) {
	if (!t[x].lazy) return;
	t[lx].sum *= -1; t[lx].lazy ^= 1;
	t[rx].sum *= -1; t[rx].lazy ^= 1;
	int Min, Max;
	Max = -t[lx].mn; Min = -t[lx].mx;
	t[lx].mx = Max; t[lx].mn = Min;
	Max = -t[rx].mn; Min = -t[rx].mx;
	t[rx].mx = Max; t[rx].mn = Min;
	t[x].lazy = 0;
}
inline void changePoint(int x, int pos, int val) {
	if (t[x].l == t[x].r) {
		t[x].sum = t[x].mx = t[x].mn = val;
		return;
	}
	pushdown(x);
	int mid = t[x].l + t[x].r >> 1;
	if (pos <= mid) changePoint(lx, pos, val);
	else changePoint(rx, pos, val);
	pushup(x);
}
inline void changeMul(int x, int l, int r) {
	if (l > r) return;
	if (l <= t[x].l && t[x].r <= r) {
		t[x].sum *= -1; t[x].lazy ^= 1;
		int Max = -t[x].mn, Min = -t[x].mx;
		t[x].mx = Max; t[x].mn = Min;
		return;
	}
	pushdown(x);
	int mid = t[x].l + t[x].r >> 1;
	if (l <= mid) changeMul(lx, l, r);
	if (r > mid) changeMul(rx, l, r);
	pushup(x);
}
inline int queryMin(int x, int l, int r) {
	if (l > r) return 19260817; 
	if (l <= t[x].l && t[x].r <= r) return t[x].mn;
	pushdown(x);
	int Min = 19260817, mid = t[x].l + t[x].r >> 1;
	if (l <= mid) Min = min(Min, queryMin(lx, l, r));
	if (r > mid) Min = min(Min, queryMin(rx, l, r));
	return Min; 
}
inline int queryMax(int x, int l, int r) {
	if (l > r) return -19260817;
	if (l <= t[x].l && t[x].r <= r) return t[x].mx;
	pushdown(x);
	int Max = -19260817, mid = t[x].l + t[x].r >> 1;
	if (l <= mid) Max = max(Max, queryMax(lx, l, r));
	if (r > mid) Max = max(Max, queryMax(rx, l, r));
	return Max;
}
inline int querySum(int x, int l, int r) {
	if (l > r) return 0;
	if (l <= t[x].l && t[x].r <= r) return t[x].sum;
	pushdown(x);
	int res = 0, mid = t[x].l + t[x].r >> 1;
	if (l <= mid) res += querySum(lx, l, r);
	if (r > mid) res += querySum(rx, l, r);
	return res;
}
inline void dfs1(int x, int dad) {
	dep[x] = dep[dad] + 1;
	siz[x] = 1; f[x] = dad;
	for (int i = lst[x]; i; i = e[i].nxt) {
		int to = e[i].to;
		if (to == dad) continue;
		a[to] = e[i].val;
		dfs1(to, x);
		siz[x] += siz[to];
		if (siz[son[x]] < siz[to]) son[x] = to;
	}
}
inline void dfs2(int x, int T) {
	if (!x) return;
	Top[x] = T;
	dfn[x] = ++tot;
	w[tot] = a[x];
	dfs2(son[x], T);
	for (int i = lst[x]; i; i = e[i].nxt) {
		int to = e[i].to;
		if (to == son[x] || to == f[x]) continue;
		dfs2(to, to);
	}
}
inline void change_chain(int x, int y) {
	while (Top[x] != Top[y]) {
		if (dep[Top[y]] > dep[Top[x]]) swap(x, y);
		int T = Top[x];
		changeMul(1, dfn[T], dfn[x]);
		x = f[T];
	}
	if (dep[x] > dep[y]) swap(x, y);
	changeMul(1, dfn[x] + 1, dfn[y]);
}
inline int querySum_chain(int x, int y) {
	int res = 0;
	while (Top[x] != Top[y]) {
		if (dep[Top[x]] < dep[Top[y]]) swap(x, y);
		int T = Top[x];
		res += querySum(1, dfn[T], dfn[x]);
		x = f[T];
	}
	if (dep[x] > dep[y]) swap(x, y);
	return res + querySum(1, dfn[x] + 1, dfn[y]);
}
inline int queryMax_chain(int x, int y) {
	int res = -19260817;
	while (Top[x] != Top[y]) {
		if (dep[Top[x]] < dep[Top[y]]) swap(x, y);
		int T = Top[x];
		res = max(res, queryMax(1, dfn[T], dfn[x]));
		x = f[T];
	}
	if (dep[x] > dep[y]) swap(x, y);
	return max(res, queryMax(1, dfn[x] + 1, dfn[y]));
}
inline int queryMin_chain(int x, int y) {
	int res = 19260817;
	while (Top[x] != Top[y]) {
		if (dep[Top[x]] < dep[Top[y]]) swap(x, y);
		int T = Top[x];
		res = min(res, queryMin(1, dfn[T], dfn[x]));
		x = f[T];
	}
	if (dep[x] > dep[y]) swap(x, y);
	return min(res, queryMin(1, dfn[x] + 1, dfn[y]));
}
signed main() {
	freopen("travel.in", "r", stdin);
	freopen("travel.out", "w", stdout);
	n = read(); cnt = 1;
	for (int i = 1; i < n; i++) {
		int u = read() + 1, v = read() + 1, w = read();
		add(u, v, w); add(v, u, w);
		E[i].u = u; E[i].v = v;
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	q = read();
	while (q--) {
		char c[5]; int x, y;
		scanf("%s", c + 1); x = read(); y = read();
		if (c[1] == 'C') {
			int u = E[x].u, v = E[x].v;
			if (dep[u] > dep[v]) changePoint(1, u, y);
			else changePoint(1, v, y);
		}
		if (c[1] == 'N') change_chain(x + 1, y + 1);
		if (c[1] == 'S') printf("%lld\n", querySum_chain(x + 1, y + 1));
		if (c[1] == 'M' && c[2] == 'A') printf("%lld\n", queryMax_chain(x + 1, y + 1));
		if (c[1] == 'M' && c[2] == 'I') printf("%lld\n", queryMin_chain(x + 1, y + 1));
	}
	return 0;
}
2021/10/18 13:46
加载中...