说句闲话,学习树链剖分的最好方法就是A了这道题(然而我炸了)
查看原帖
说句闲话,学习树链剖分的最好方法就是A了这道题(然而我炸了)
249736
Seg_Tree楼主2020/7/29 15:14

求大佬帮忙康康

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

typedef long long ll;
const int N = 200010;
const int inf = 1e9 + 7;

int n, m, dis[N];
struct Edge {
	int to, nxt, val;
}edge[N];
int head[N], tot;
int top[N], size[N], d[N], fa[N], cnt, son[N], id[N], w[N];
struct node {
	int maxx, minn, sum, tag;
}tree[N << 2];

void add_edge(int x, int y, int z) {
	edge[++tot].to = y;
	edge[tot].val = z;
	edge[tot].nxt = head[x];
	head[x] = tot;
}
void dfs1(int u) {
	size[u] = 1;
	for(int i = head[u]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(v == fa[u]) continue;
		fa[v] = u; d[v] = d[u] + 1; dis[v] = edge[i].val;
		dfs1(v);
		size[u] += size[v];
		if(size[v] > size[son[u]]) son[u] = v;
	}
}
void dfs2(int u, int T) {
	id[u] = ++ cnt;
	w[cnt] = dis[u];
	top[u] = T;
	if(son[u]) dfs2(son[u], T);
	for(int i = head[u]; i; i = edge[i].nxt) {
		int v = edge[i].to;
		if(v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}
//-----------------------------------------------------
void pushdown(int u, int x, int y) {
	int mark_1, mark_2;
	if(tree[u].tag == -1) {
		mark_1 = tree[u << 1].maxx, mark_2 = tree[u << 1].minn;
		tree[u << 1].sum = -tree[u << 1].sum;
		tree[u << 1].maxx = -mark_2;
		tree[u << 1].minn = -mark_1;
		
		mark_1 = tree[u << 1 | 1].maxx, mark_2 = tree[u << 1 | 1].minn;
		tree[u << 1 | 1].sum = -tree[u << 1 | 1].sum;
		tree[u << 1 | 1].maxx = -mark_2;
		tree[u << 1 | 1].minn = -mark_1;
		
		tree[u].tag = 1;
	}
}
void pushup(int u) {
	tree[u].sum = tree[u << 1].sum + tree[u << 1 | 1].sum;
	tree[u].maxx = max(tree[u << 1].maxx, tree[u << 1 | 1].maxx);
	tree[u].minn = min(tree[u << 1].minn, tree[u << 1 | 1].minn);
}
void build(int u, int x, int y) {
	tree[u].tag = 1;
	if(x == y) {
		tree[u].maxx = tree[u].minn = tree[u].sum = w[x];
		return ;
	}
	int mid = (x + y) >> 1;
	build(u << 1, x, mid), build(u << 1 | 1, mid + 1, y);
	pushup(u);
}
node query(int u, int x, int y, int a, int b) {
	if(a <= x && b >= y) return tree[u];
	int mid = (x + y) >> 1;
	if(b <= mid) return query(u << 1, x, mid, a, b);
	if(a > mid) return query(u << 1 | 1, mid + 1, y, a, b);
	node t, t_l, t_r;
	t_l = query(u << 1, x, mid, a, b);
	t_r = query(u << 1 | 1, mid + 1, y, a, b);
	t.sum = t_l.sum + t_r.sum;
	t.maxx = max(t_l.maxx, t_r.maxx);
	t.minn = min(t_l.minn, t_r.minn);
	return t;
}
node Query(int x, int y) {
	node t, res;
	t.sum = 0, t.maxx = -inf, t.minn = inf;
	while(top[x] != top[y]) {
		if(d[top[x]] < d[top[y]]) swap(x, y);
		res = query(1, 1, n, id[top[x]], id[x]);
		t.sum += res.sum;
		t.maxx = max(t.maxx, res.maxx);
		t.minn = min(t.minn, res.minn);
		x = fa[top[x]];
	}
	if(d[x] > d[y]) swap(x, y);
	if(x != y) {
		res = query(1, 1, n, id[x] + 1, id[y]);
		t.sum += res.sum;
		t.maxx = max(t.maxx, res.maxx);
		t.minn = min(t.minn, res.minn);
	}
	return t;
}
void change(int u, int x, int y, int a, int k) {
	if(x == a && y == a) {
		tree[u].maxx = tree[u].minn = tree[u].sum = k;
		return ;
	}
	pushdown(u, x, y);
	int mid = (x + y) >> 1;
	if(a <= mid) change(u << 1, x, mid, a, k);
	else change(u << 1 | 1, mid + 1, y, a, k);
	pushup(u);
}
void change_1(int u, int x, int y, int a, int b) {
	if(a <= x && b >= y) {
		int mark_1 = tree[u].maxx, mark_2 = tree[u].minn;
		tree[u].sum = -tree[u].sum;
		tree[u].maxx = -mark_2;
		tree[u].minn = -mark_1;
		tree[u].tag *= -1;
		return ;
	}
	pushdown(u, x, y);
	int mid = (x + y) >> 1;
	if(a <= mid) change_1(u << 1, x, mid, a, b);
	if(b > mid) change_1(u << 1 | 1, mid + 1, y, a, b);
	pushup(u);
}
void Change(int x, int y) {
	while(top[x] != top[y]) {
		if(d[top[x]] < d[top[y]]) swap(x, y);
		change_1(1, 1, n, id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if(d[x] > d[y]) swap(x, y);
	if(x != y) change_1(1, 1, n, id[x] + 1, id[y]);
}
string s;
int main () {
	scanf("%d", &n);
	for(int i = 1; i < n; i ++ ) {
		int u, v, w; scanf("%d %d %d", &u, &v, &w); u ++ , v ++ ; 
		add_edge(u, v, w), add_edge(v, u, w);
	}
	fa[1] = 1;
	dfs1(1);
	dfs2(1, 1);
	build(1, 1, n);
	scanf("%d", &m);
	while(m -- ) {
		cin >> s;
		if(s == "SUM") {
			int l, r; scanf("%d %d", &l, &r); l ++ , r ++ ;
			printf("%d\n", Query(l, r).sum);
		}
		if(s == "C") {
			int i, k; scanf("%d %d", &i, &k); i ++ ;
			change(1, 1, n, id[i], k); 
		}
		if(s == "N") {
			int l, r; scanf("%d %d", &l, &r); l ++ , r ++ ;
			//cout << "fuck" << endl;
			Change(l, r);
		}
		if(s == "MAX") {
			int l, r; scanf("%d %d", &l, &r); l ++ , r ++ ;
			printf("%d\n", Query(l, r).maxx);
		}
		if(s == "MIN") {
			int l, r; scanf("%d %d", &l, &r); l ++ , r ++ ;
			printf("%d\n", Query(l, r).minn);
		}
	}
	return 0;
}
2020/7/29 15:14
加载中...