树剖30分只有换根有问题
查看原帖
树剖30分只有换根有问题
335477
ker_xyxyxyx_xxs楼主2021/8/14 17:21

可以保证修改没有问题,换根出了问题,过了1、2、5

而且小数据换根也没问题。。就很奇葩

# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cmath>
using namespace std;

typedef long long ll;

const int N = 5e5 + 5;
const int inf = 1e18;

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] , W[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] , 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 , minv;
}Node;
Node tr[N * 4];

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

void pushdown(int p) {
	if (tr[p].lazy) {
		tr[p << 1].lazy = tr[p << 1 | 1].lazy = tr[p << 1].minv = tr[p << 1 | 1].minv = tr[p].lazy;
		tr[p].lazy = 0;
	}
}

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

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

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

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

int root;

int F[N][60];
int K;
void dfs_lca(int u , int fa) {
	F[u][0] = fa;
	for (int j = 1 ; ; j ++) {
		F[u][j] = F[F[u][j - 1]][j - 1];
		if (F[u][j] == 0) {
			K = max(K , j - 1);
			break;
		}
	}
	for (int j = elast[u] ; j ; j = edge[j].next) {
		int v = edge[j].y;
		if (v != fa) dfs_lca(v , u);
	}
}

int get_lca(int u , int v) {
	if (u == v) return u;
	if (dep[u] < dep[v]) swap(u , v);
	for (int j = K ; j >= 0 ; j --) {
		if (dep[F[u][j]] >= dep[v]) u = F[u][j];
	}
	if (u == v) return u;
	for (int j = K ; j >= 0 ; j --) {
		if (F[u][j] != F[v][j]) {
			u = F[u][j] , v = F[v][j];
		}
	}
	return F[u][0];
}

int main() {
	cin >> n >> m;
	K = log2(n);
	for (int i = 1 ; i < n ; i ++) {
		cin >> x >> y;
		add(x , y) , add(y , x);
	}
	for (int i = 1 ; i <= n ; i ++) {
		cin >> W[i];
	}
	cin >> root;
	dfs1(root , 0);
	dfs2(root , root);
	dfs_lca(root , 0);
	build(1 , 1 , n);
	int ans = 0;
	while (m --) {
		int opt;
		cin >> opt >> x;
		if (opt == 1) {
			root = x;
		}
		if (opt == 2) {
			scanf("%d%d" , &y , &z);
			change(x , y , z);
		}
		if (opt == 3) {
			if (x == root) {
				printf("%d\n" , query(1 , 1 , n));
			    continue;
			}
			if (get_lca(x , root) != x || get_lca(x , root) == root) {
				printf("%d\n" , query(1 , id[x] , id[x] + siz[x] - 1));
			    continue;
			}
			if (get_lca(x , root) == x) {
				int ans = 0;
				for (int j = elast[x] ; j ; j = edge[j].next) {
					int v = edge[j].y;
					if (get_lca(v , root) == v) {
						printf("%d\n" , min(query(1 , 1 , id[v]) , query(1 , id[v] + siz[v] , n)));
						break;
					}

				}
			}
		}
	}
	return 0;
}
2021/8/14 17:21
加载中...