萌新刚学OI,求助树剖WA92pts,不知道哪里被Hack了
查看原帖
萌新刚学OI,求助树剖WA92pts,不知道哪里被Hack了
335477
ker_xyxyxyx_xxs楼主2021/8/9 13:05

倒数第二个测试点

# include <iostream>
# include <cstdio>

using namespace std;

typedef long long ll;

const int N = 2e6 + 5;
const int inf = 1e13;

typedef struct {
	int x , y , next;
}Edge;
Edge edge[N];

int E = 0 , elast[N];

void add(int x , int y ) {
	E ++;
	edge[E].x = x;
	edge[E].y = y;
	edge[E].next = elast[x];
	elast[x] = E;
}

int f[N] , dep[N] , son[N] , siz[N];

void dfs1(int x , int fa) {
	dep[x] = dep[fa] + 1;
	f[x] = fa;
	siz[x] = 1;
	int maxv = -1;
	for (int i = elast[x] ; i ; i = edge[i].next) {
		int y = edge[i].y;
		if (y != fa) {
			dfs1(y , x);
			siz[x] += siz[y];
			if (siz[y] > maxv) son[x] = y , maxv = siz[y];
		}
	}
}

int top[N] , id[N] , w[N] , W[N] , Cnt = 0;

int n , m , x , y , z;

void dfs2(int x , int Top) {
	id[x] = ++ Cnt;
	w[Cnt] = W[x];
	top[x] = Top;
	if (!son[x]) return ;
	dfs2(son[x] , Top);
	for (int i = elast[x] ; i ; i = edge[i].next) {
		int y = edge[i].y;
		if (y != f[x] && y != son[x]) dfs2(y , y);
	}
}

typedef struct {
	int l , r , lazy , maxv , minv , sum;
}Node;
Node tr[N * 4];

void pushup(int p) {
	tr[p].minv = min(tr[p << 1].minv , tr[p << 1 | 1].minv);
	tr[p].maxv = max(tr[p << 1].maxv , tr[p << 1 | 1].maxv);
	tr[p].sum = tr[p << 1].sum + tr[p << 1 | 1].sum;
}

void pushdown(int p) {
	if (tr[p].lazy) {
		tr[p].lazy ^= 1;
		tr[p << 1].lazy ^= 1;
		tr[p << 1 | 1].lazy ^= 1;
		tr[p << 1].sum = -tr[p << 1].sum;
		tr[p << 1].minv = -tr[p << 1].minv;
		tr[p << 1].maxv = -tr[p << 1].maxv;
		tr[p << 1 | 1].sum = -tr[p << 1 | 1].sum;
		tr[p << 1 | 1].minv = -tr[p << 1 | 1].minv;
		tr[p << 1 | 1].maxv = -tr[p << 1 | 1].maxv;
		swap(tr[p << 1].minv , tr[p << 1].maxv);
		swap(tr[p << 1 | 1].minv , tr[p << 1 | 1].maxv);
	}
} 

void build(int p , int x , int y) {
	tr[p].l = x;
	tr[p].r = y;
	if (x == y) {
		tr[p].minv = tr[p].maxv = tr[p].sum = w[x];
		return ;
	} else {
		int mid = (x + y) >> 1;
		build(p << 1 , x , mid) , build(p << 1 | 1 , mid + 1 , y);
		pushup(p);
	}
}

void change(int p , int x , int d) {
	if (tr[p].l == tr[p].r) {
		tr[p].sum = tr[p].maxv = tr[p].minv = d;
		return ;
	} else {
		pushdown(p);
		int mid = (tr[p].l + tr[p].r) >> 1;
		if (x <= mid) change(p << 1 , x , d);
		else change(p << 1 | 1 , x , d);
		pushup(p);
	}
}

void modify(int p , int x , int y) {
	if (x <= tr[p].l && tr[p].r <= y) {
		tr[p].lazy ^= 1;
		tr[p].sum = -tr[p].sum;
		tr[p].maxv = -tr[p].maxv;
		tr[p].minv = -tr[p].minv;
		swap(tr[p].minv , tr[p].maxv);
		return ;
	} else {
		pushdown(p);
		int mid = (tr[p].l + tr[p].r) >> 1;
		if (x <= mid) modify(p << 1 , x , y);
		if (y > mid) modify(p << 1 | 1 , x , y);
		pushup(p);
	}
}

int get_sum(int p , int x , int y) {
	if (x <= tr[p].l && tr[p].r <= y) return tr[p].sum;
	else {
		pushdown(p);
		int mid = (tr[p].l + tr[p].r) >> 1 , ans = 0;
		if (x <= mid) ans += get_sum(p << 1 , x , y);
		if (y > mid) ans += get_sum(p << 1 | 1 , x , y);
		return ans; 
	}
}

int get_min(int p , int x , int y) {
	if (x <= tr[p].l && tr[p].r <= y) return tr[p].minv;
	else {
		pushdown(p);
		int mid = (tr[p].l + tr[p].r) >> 1 , ans = inf;
		if (x <= mid) ans = min(ans , get_min(p << 1 , x , y));
		if (y > mid) ans = min(ans , get_min(p << 1 | 1 , x , y));
		return ans; 
	}
}

int get_max(int p , int x , int y) {
	if (x <= tr[p].l && tr[p].r <= y) return tr[p].maxv;
	else {
		pushdown(p);
		int mid = (tr[p].l + tr[p].r) >> 1 , ans = -inf;
		if (x <= mid) ans = max(ans , get_max(p << 1 , x , y));
		if (y > mid) ans = max(ans , get_max(p << 1 | 1 , x , y));
		return ans; 
	}
}

void update(int x , int y) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x , y);
		modify(1 , id[top[x]] , id[x]);
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x , y);
	if (x != y) modify(1 , id[x] + 1 , id[y]);
}

int query_sum(int x , int y) {
	int ans = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x , y);
		ans += get_sum(1 , id[top[x]] , id[x]);
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x , y);
	if (x != y) ans += get_sum(1 , id[x] + 1 , id[y]);
	return ans;
}

int query_min(int x , int y) {
	int ans = inf;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x , y);
		ans = min(ans , get_min(1 , id[top[x]] , id[x]));
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x , y);
	if (x != y) ans = min(ans , get_min(1 , id[x] + 1 , id[y]));
	return ans;
}

int query_max(int x , int y) {
	int ans = -inf;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x , y);
		ans = max(ans , get_max(1 , id[top[x]] , id[x]));
		x = f[top[x]];
	}
	if (dep[x] > dep[y]) swap(x , y);
	if (x != y) ans = max(ans , get_max(1 , id[x] + 1 , id[y]));
	return ans;
}

int Ver[N] , ver[N];
int main() {
	cin >> n;
	for (int i = 1 ; i <= n - 1 ; i ++) {
		scanf("%d%d%d" , &x , &y , &z);
		x ++ , y ++;
		add(x , y);
		add(y , x);
		W[y] = z;
		Ver[i] = x;
		ver[i] = y;
	}
	cin >> m;
	dfs1(1 , 0);
	dfs2(1 , 1);
	build(1 , 1 , n);
	while (m --) {
		char s[3];
		scanf("%s" , &s);
		if (s[0] == 'C') {
			scanf("%d%d" , &x , &y);
			if (dep[Ver[x]] > dep[ver[x]]) change(1 , id[Ver[x]] , y);
			else change(1 , id[ver[x]] , y);
			
		}
		if (s[0] == 'N') {
			scanf("%d%d" , &x , &y);
			x ++ , y ++;
			update(x , y);
		}
		if (s[0] == 'S') {
			scanf("%d%d" , &x , &y);
			x ++ , y ++;
			printf("%d\n" , query_sum(x , y));
		}
		if (s[0] == 'M' && s[1] == 'A') {
			scanf("%d%d" , &x , &y);
			x ++ , y ++;
			printf("%d\n" , query_max(x , y));
		}
		if (s[0] == 'M' && s[1] == 'I') {
			scanf("%d%d" , &x , &y);
			x ++ , y ++;
			printf("%d\n" , query_min(x , y));
		}
	}
	return 0;
}
2021/8/9 13:05
加载中...