社区讨论

萌新刚学数据结构,Wa on test 5

SP2939QTREE5 - Query on a tree V参与者 1已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo1mipja
此快照首次捕获于
2023/10/22 23:28
2 年前
此快照最后确认于
2023/11/03 00:13
2 年前
查看原帖
有没有佬帮帮忙啊,哭哭 son 维护 节点虚子树内的dep
front 记录 son的最小值
minn 维护 平衡树内的最小dep
val 记录 当前节点的贡献
res 记录 实路径(平衡树)的最小贡献
CPP
#include<set>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100017 
using namespace std;

const int INF = 1e7 + 7;
vector<int>to[N];set<pair<int,int> >son[N];
int col[N],dep[N],fa[N],ch[N][2],r[N],front[N],minn[N],val[N],res[N],st[N],top;

void dfs(int u,int f){
	dep[u] = dep[f] + 1;
	for(int i = 0;i < to[u].size();i += 1){
		int v = to[u][i];
		if(v == f)continue;
		dfs(v,u);
	}
}

void pushup(int x){
	val[x] = front[x] - 2*dep[x];
	minn[x] = min(front[x],min(minn[ch[x][0]],minn[ch[x][1]]));
	res[x] = min(val[x],min(res[ch[x][0]],res[ch[x][1]]));
}

void add(int x,int y){
	if(!y)return;
	if(minn[y] != INF)son[x].insert(make_pair(-minn[y],y));
	if(son[x].size())front[x] = -(*son[x].begin()).first;
	else front[x] = INF;
}

void del(int x,int y){
	if(!y)return;
	if(minn[y] != INF)son[x].erase(make_pair(-minn[y],y));
	if(son[x].size())front[x] = -(*son[x].begin()).first;
	else front[x] = INF;
}

bool isroot(int x){
	return (ch[fa[x]][0] != x) & (ch[fa[x]][1] != x);
}

void rotate(int x){
	int y = fa[x],z = fa[y];
	bool f = ch[y][1] == x,g = ch[z][1] == y;
	fa[x] = z;if(!isroot(y))ch[z][g] = x;
	ch[y][f] = ch[x][f^1],fa[ch[x][f^1]] = y;
	ch[x][f^1] = y;fa[y] = x;
	pushup(y),pushup(x);
}

void splay(int x){
	while(!isroot(x)){
		int y = fa[x],z = fa[y];
		if(!isroot(y)){
			bool f = ch[y][1] == x,g = ch[z][1] == y;
			if(f ^ g)rotate(x);
			else rotate(y);
		}
		rotate(x);
	}
}

void access(int x){
	for(int y = 0;x;y = x,x = fa[x]){
		splay(x);
		del(x,y);add(x,ch[x][1]);
		ch[x][1] = y;pushup(x);
	}
}

void link(int x,int y){
	access(y),splay(y);
	fa[x] = y;add(y,x);pushup(y);
}

void modify(int x){
	access(x),splay(x);
	col[x] ^= 1;
	if(col[x])son[x].insert(make_pair(-dep[x],x));
	else son[x].erase(make_pair(-dep[x],x));
	if(son[x].size())front[x] = -(*son[x].begin()).first;
	else front[x] = INF;
	pushup(x);
}

void query(int x){
	access(x),splay(x);
	if(res[x] >= N)cout << -1 << endl;
	else cout << dep[x] + res[x] << endl;
}

int main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	int n,op,x,y,q;
	cin >> n;
	for(int i = 1;i < n;i += 1){
		cin >> x >> y;
		to[x].push_back(y),to[y].push_back(x);
	} 
	dfs(1,0);
	for(int i = 0;i <= n;i += 1)front[i] = minn[i] = res[i] = val[i] = INF;
	for(int i = 1;i <= n;i += 1)
		for(int j = 0;j < to[i].size();j += 1)
			if(i < to[i][j])link(to[i][j],i);
	cin >> q;
	while(q--){
		cin >> op >> x;
		if(!op)modify(x);
		else query(x);
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...