树剖+线段树10pts WAon#1~10 AC#11 求调玄关
查看原帖
树剖+线段树10pts WAon#1~10 AC#11 求调玄关
1284582
F_L_Bird楼主2025/1/30 22:58

调一晚上条不动了,代码已经格式化,望调

#include<iostream>
#include<vector>
#include<string>
using namespace std;

int n,m,s,p,cnt;
int a[100005],dep[100005],fa[100005],son[100005],siz[100005],top[100005],id[100005],out[100005],temp[100005];
const long long INF = 0x3f3f3f3f3f3f3f3f;

struct Node {
	int l,r,add,cov = -1;
	long long mx;
} node[400005];

struct Edge {
	int u,v,w;
} edge[100005];

vector<Edge> e[100005];

inline void swap(int &x,int &y) {
	y += x;
	x = y - x;
	y -= x;
	return;
}

inline void push_up(int i) {
	node[i].mx = max(node[2 * i].mx,node[2 * i + 1].mx);
	return;
}

inline void push_down(int i) {
	if(node[i].cov != -1) {
		node[2 * i].mx = node[i].cov;
		node[2 * i].add = 0;
		node[2 * i].cov = node[i].cov;
		node[2 * i + 1].mx = node[i].cov;
		node[2 * i + 1].add = 0;
		node[2 * i + 1].cov = node[i].cov;
		node[i].cov = -1;
	} else {
		node[2 * i].mx += node[i].add;
		node[2 * i].add += node[i].add;
		node[2 * i + 1].mx += node[i].add;
		node[2 * i + 1].add += node[i].add;
	}
	return;
}

void build(int i,int l,int r) {
	node[i].l = l;
	node[i].r = r;
	if(l == r) {
		node[i].mx = a[l];
		return;
	}
	int mid = (l + r) / 2;
	build(2 * i,l,mid);
	build(2 * i + 1,mid + 1,r);
	push_up(i);
	return;
}

void modify_cover(int i,int l,int r,int k) {
	if(node[i].l > r || node[i].r < l) {
		return;
	}
	if(node[i].l >= l && node[i].r <= r) {
		node[i].mx = k;
		node[i].cov = k;
		node[i].add = 0;
		return;
	}
	push_down(i);
	modify_cover(2 * i,l,r,k);
	modify_cover(2 * i + 1,l,r,k);
	push_up(i);
	return;
}

void modify_add(int i,int l,int r,int k) {
	if(node[i].l > r || node[i].r < l) {
		return;
	}
	if(node[i].l >= l && node[i].r <= r) {
		if(node[i].cov == -1) {
			node[i].add += k;
		} else {
			node[i].cov += k;
		}
		node[i].mx += k;
		return;
	}
	push_down(i);
	modify_add(2 * i,l,r,k);
	modify_add(2 * i + 1,l,r,k);
	push_up(i);
	return;
}

long long query(int i,int l,int r) {
	if(node[i].l > r || node[i].r < l) {
		return -INF;
	}
	if(node[i].l >= l && node[i].r <= r) {
		return node[i].mx;
	}
	push_down(i);
	return max(query(2 * i,l,r),query(2 * i + 1,l,r));
}

void dfs1(int u,int f) {
	fa[u] = f;
	dep[u] = dep[f] + 1;
	siz[u] = 1;
	int mx = -1;
	for(int i = 0; i < int(e[u].size()); i += 1) {
		int v = e[u][i].v;
		if(v != f) {
			dfs1(v,u);
			siz[u] += siz[v];
			if(mx < siz[v]) {
				mx = siz[v];
				son[u] = v;
			}
		}
	}
	return;
}

void dfs2(int u,int t) {
	cnt += 1;
	id[u] = cnt;
	top[u] = t;
	if(son[u] == 0) {
		out[u] = cnt;
		return;
	} else {
		dfs2(son[u],t);
	}
	for(int i = 0; i < int(e[u].size()); i += 1) {
		int v = e[u][i].v;
		if(v != fa[u] && v != son[u]) {
			dfs2(v,v);
		}
	}
	out[u] = cnt;
	return;
}

int main() {
	//freopen("P4315_1.in","r",stdin);
	//freopen("P4315_1.ans","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n;
	int u,v,w,k;
	for(int i = 1; i <= n - 1; i += 1) {
		cin>>u>>v>>w;
		edge[i] = Edge{u,v,w};
		e[u].push_back(Edge{u,v,w});
		e[v].push_back(Edge{v,u,w});
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i = 1; i <= n - 1; i += 1) {
		a[max(id[edge[i].u],id[edge[i].v])] = edge[i].w;
	}
	build(1,1,n);
	string opt;
	while(cin>>opt) {
		if(opt == "Stop") {
			break;
		} else if(opt == "Change") {
			cin>>k>>w;
			modify_cover(1,max(id[edge[k].u],id[edge[k].v]),max(id[edge[k].u],id[edge[k].v]),w);
		} else if(opt == "Cover") {
			cin>>u>>v>>w;
			if(u == v) {
				continue;
			}
			while(top[u] != top[v]) {
				if(dep[top[u]] < dep[top[v]]) {
					swap(u,v);
				}
				modify_cover(1,id[top[u]],id[u],w);
				u = fa[top[u]];
			}
			modify_cover(1,min(id[u],id[v]) + 1,max(id[u],id[v]),w);
		} else if(opt == "Add") {
			cin>>u>>v>>w;
			if(u == v) {
				continue;
			}
			while(top[u] != top[v]) {
				if(dep[top[u]] < dep[top[v]]) {
					swap(u,v);
				}
				modify_add(1,id[top[u]],id[u],w);
				u = fa[top[u]];
			}
			modify_add(1,min(id[u],id[v]) + 1,max(id[u],id[v]),w);
		} else {
			cin>>u>>v;
			if(u == v) {
				cout<<0<<'\n';
				continue;
			}
			long long res = -INF;
			while(top[u] != top[v]) {
				if(dep[top[u]] < dep[top[v]]) {
					swap(u,v);
				}
				res = max(query(1,id[top[u]],id[u]),res);
				u = fa[top[u]];
			}
			res = max(res,query(1,min(id[u],id[v]) + 1,max(id[u],id[v])));
			cout<<res<<'\n';
		}
	}
	return 0;
}
2025/1/30 22:58
加载中...