88pts RE on #12 (+ O2 后 TLE on #12)
查看原帖
88pts RE on #12 (+ O2 后 TLE on #12)
911417
_Z_F_R_楼主2024/1/6 15:30

rt

#include <bits/stdc++.h> 
#define ll long long
using namespace std;

const int N = 200005;
struct tNode {
	int fa, dep, hson, top, siz, dfn;
	ll val;
}a[N];
int rk[N], edgeid[N];
vector<pair<pair<int, ll>, int> > edge[N];
int n, m;
void Dfs1(int x, int fa) {
	a[x].fa = fa, a[x].dep = a[fa].dep + 1, a[x].siz = 1;
	for(auto v : edge[x]) {
		auto info = v.first;
		int id = v.second;
		if(info.first == fa) {
			edgeid[id] = x;
			a[x].val = info.second;
//			cout << x << ' ' << fa << endl;
			continue;
		}
		Dfs1(info.first, x);
		a[x].siz += a[info.first].siz;
		if(a[a[x].hson].siz > a[info.first].siz) {
			a[x].hson = info.first;
		}
	}
} 
int cntdfn = 0;
void Dfs2(int x, int top) {
	int fa = a[x].fa;
	a[x].top = top, a[x].dfn = ++cntdfn;
	rk[cntdfn] = x;
	if(a[x].hson) {
		Dfs2(a[x].hson, top);
	}
	for(auto v : edge[x]) {
		auto info = v.first;
		int id = v.second;
		if(info.first == fa || info.first == a[x].hson) {
			continue;
		}
		Dfs2(info.first, info.first);
	}
}
struct SegTree {
	struct tNode {
		int l, r, neg;
		ll sum, maxv, minv;
	}tree[N << 2];
	void PushUp(int x) {
		tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum;
		tree[x].maxv = max(tree[x << 1].maxv, tree[x << 1 | 1].maxv);
		tree[x].minv = min(tree[x << 1].minv, tree[x << 1 | 1].maxv);
	}
	void Build(int x, int l, int r) {
		tree[x].l = l, tree[x].r = r;
		if(l == r) {
			tree[x].sum = tree[x].maxv = tree[x].minv = a[rk[l]].val;
			return ;
		}
		int mid = (l + r) >> 1;
		Build(x << 1, l, mid);
		Build(x << 1 | 1, mid + 1, r);
		PushUp(x);
	}
	void PushDown(int x) {
		if(tree[x].neg) {
			tree[x << 1].neg ^= 1, tree[x << 1 | 1].neg ^= 1;
			tree[x << 1].sum = -tree[x << 1].sum, tree[x << 1 | 1].sum = -tree[x << 1 | 1].sum;
			swap(tree[x << 1].maxv, tree[x << 1].minv), swap(tree[x << 1 | 1].maxv, tree[x << 1 | 1].minv);
			tree[x << 1].maxv = -tree[x << 1].maxv, tree[x << 1 | 1].maxv = -tree[x << 1 | 1].maxv;
			tree[x << 1].minv = -tree[x << 1].minv, tree[x << 1 | 1].minv = -tree[x << 1 | 1].minv;
			tree[x].neg = 0;
		}
	}
	void Modify_sig(int x, int mp, ll v) {
		int l = tree[x].l, r = tree[x].r;
		if(l == r) {
			tree[x].sum = tree[x].maxv = tree[x].minv = v;
			return ;
		}
		int mid = (l + r) >> 1;
		PushDown(x);
		if(mp <= mid) {
			Modify_sig(x << 1, mp, v);
		}
		else {
			Modify_sig(x << 1 | 1, mp, v);
		}
		PushUp(x);
	}
	void Modify_neg(int x, int ml, int mr) {
		int l = tree[x].l, r = tree[x].r;
//		cout << x << ' ' << ml << ' ' << mr << ' ' << l << ' ' << r << endl;
		if(ml <= l && r <= mr) {
//			cout << "Modified " << x << endl;
			tree[x].sum = -tree[x].sum, swap(tree[x].maxv, tree[x].minv);
			tree[x].maxv = -tree[x].maxv, tree[x].minv = -tree[x].minv;
			tree[x].neg ^= 1;
			return ;
		}
		int mid = (l + r) >> 1;
		PushDown(x);
		if(ml <= mid) {
			Modify_neg(x << 1, ml, mr);
		}
		if(mr > mid) {
			Modify_neg(x << 1 | 1, ml, mr);
		}
		PushUp(x);
	}
	ll Query_sum(int x, int ql, int qr) {
		int l = tree[x].l, r = tree[x].r;
		if(ql <= l && r <= qr) {
			return tree[x].sum;
		}
		int mid = (l + r) >> 1;
		PushDown(x);
		ll res = 0;
		if(ql <= mid) {
			res += Query_sum(x << 1, ql, qr);
		}
		if(qr > mid) {
			res += Query_sum(x << 1 | 1, ql, qr);
		}
		return res;
	}
	ll Query_maxv(int x, int ql, int qr) {
		int l = tree[x].l, r = tree[x].r;
		if(ql <= l && r <= qr) {
			return tree[x].maxv;
		}
		int mid = (l + r) >> 1;
		PushDown(x);
		ll res = LONG_LONG_MIN;
		if(ql <= mid) {
			res = max(res, Query_maxv(x << 1, ql, qr));
		}
		if(qr > mid) {
			res = max(res, Query_maxv(x << 1 | 1, ql, qr));
		}
		return res;
	}
	ll Query_minv(int x, int ql, int qr) {
		int l = tree[x].l, r = tree[x].r;
		if(ql <= l && r <= qr) {
			return tree[x].sum;
		}
		int mid = (l + r) >> 1;
		PushDown(x);
		ll res = LONG_LONG_MAX;
		if(ql <= mid) {
			res = min(res, Query_minv(x << 1, ql, qr));
		}
		if(qr > mid) {
			res = min(res, Query_minv(x << 1 | 1, ql, qr));
		}
		return res;
	}
	void Out() {
		int i = 1;
		while(tree[i].l) {
			printf("tree[%d] [%d, %d] : sum = %lld, maxv = %lld, minv = %lld, neg = %lld\n", i, tree[i].l, tree[i].r, tree[i].sum, tree[i].maxv, tree[i].minv, tree[i].neg);
			i++;
		}
	}
}segtree;
void Modify_Edge(int x, ll v) {
	segtree.Modify_sig(1, a[edgeid[x]].dfn, v);
}
void Modify_Path(int u, int v) {
	while(a[u].top != a[v].top) {
		if(a[a[u].top].dep < a[a[v].top].dep) {
			swap(u, v);
		}
		segtree.Modify_neg(1, a[a[u].top].dfn, a[u].dfn);
		u = a[a[u].top].fa;
	}
	segtree.Modify_neg(1, min(a[u].dfn, a[v].dfn) + 1, max(a[u].dfn, a[v].dfn));
}
ll Query_Path_sum(int u, int v) {
	ll res = 0;
	while(a[u].top != a[v].top) {
		if(a[a[u].top].dep < a[a[v].top].dep) {
			swap(u, v);
		}
		res += segtree.Query_sum(1, a[a[u].top].dfn, a[u].dfn);
		u = a[a[u].top].fa;
	}
	res += segtree.Query_sum(1, min(a[u].dfn, a[v].dfn) + 1, max(a[u].dfn, a[v].dfn));
	return res;
}
ll Query_Path_maxv(int u, int v) {
	ll res = LONG_LONG_MIN;
	while(a[u].top != a[v].top) {
		if(a[a[u].top].dep < a[a[v].top].dep) {
			swap(u, v);
		}
		res = max(segtree.Query_maxv(1, a[a[u].top].dfn, a[u].dfn), res);
		u = a[a[u].top].fa;
	}
	res = max(segtree.Query_maxv(1, min(a[u].dfn, a[v].dfn) + 1, max(a[u].dfn, a[v].dfn)), res);
	return res;
}
ll Query_Path_minv(int u, int v) {
	ll res = LONG_LONG_MAX;
	while(a[u].top != a[v].top) {
		if(a[a[u].top].dep < a[a[v].top].dep) {
			swap(u, v);
		}
		res = min(segtree.Query_minv(1, a[a[u].top].dfn, a[u].dfn), res);
		u = a[a[u].top].fa;
	}
	res = min(segtree.Query_minv(1, min(a[u].dfn, a[v].dfn) + 1, max(a[u].dfn, a[v].dfn)), res);
	return res;
}

int main() {
//	freopen("P1505_12.in", "r", stdin);
	int i;
	scanf("%d", &n);
	for(i = 1; i < n; i++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		u++, v++;
		edge[u].push_back(make_pair(make_pair(v, w), i));
		edge[v].push_back(make_pair(make_pair(u, w), i));
	}
	Dfs1(1, 0);
//	cout << "QwQ" << endl;
	Dfs2(1, 1);
	segtree.Build(1, 1, n);
	segtree.Out();
	scanf("%d", &m);
	while(m--) {
		string op;
		cin >> op;
		if(op == "C") {
			int x;
			ll v;
			scanf("%d%lld", &x, &v);
			Modify_Edge(x, v);
		}
		else {
			int u, v;
			scanf("%d%d", &u, &v);
			u++, v++;
			if(op == "N") {
				Modify_Path(u, v);
			}
			else if(op == "SUM") {
				printf("%lld\n", Query_Path_sum(u, v));
			}
			else if(op == "MAX") {
				printf("%lld\n", Query_Path_maxv(u, v));
			}
			else {
				printf("%lld\n", Query_Path_minv(u, v));
			}
		}
//		cout << ("Finished " + op) << endl;
//		segtree.Out();
	}
}
2024/1/6 15:30
加载中...