社区讨论

求助,CF上WA on test7

CF916EJamie and Tree参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mhjdqlj6
此快照首次捕获于
2025/11/04 00:54
4 个月前
此快照最后确认于
2025/11/04 00:54
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
#define ls z[k].son[L]
#define rs z[k].son[R]
using namespace std;
typedef long long ll;
const int L = 0, R = 1;
const int N = 1e5 + 10;
int n, m, rot, root, cnt, tim;
int siz[N], dep[N], top[N], pos[N], dfn[N], a[N], f[N][25], son[N];
vector<int> G[N];
struct node{
	ll sum, addtag;
	int son[2];
}z[N << 2];
inline int read(){
	int x = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9'){
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(ch <= '9' && ch >= '0'){
		x = x * 10 + ch - '0';
		ch = getchar();	
	}
	return x * f;
}
void update(int k){
	z[k].sum = z[ls].sum + z[rs].sum;	
}
void build(int &k, int l, int r){
	k = ++cnt;
	if(l == r){
		z[k].sum = 1ll * a[pos[l]];
		return ;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	update(k);
}
void add_tag(int k, int l, int r, int d){
	z[k].addtag += 1ll * d;
	z[k].sum += 1ll * (r - l + 1) * d;	
}
void push_down(int k, int l, int r){
	if(z[k].addtag != 0){
	int mid = l + r >> 1;
	add_tag(ls, l, mid, z[k].addtag);
	add_tag(rs, mid + 1, r, z[k].addtag);
	z[k].addtag = 0;	
	}
}
void modify(int k, int l, int r, int ql, int qr, int d){
	if(ql <= l && qr >= r){
		add_tag(k, l, r, d);
		return ;
	}
	push_down(k, l, r);
	int mid = l + r >> 1;
	if(ql <= mid) modify(ls, l, mid, ql, qr, d);
	if(qr > mid) modify(rs, mid + 1, r, ql, qr, d);
	update(k);
}
ll query(int k, int l, int r, int ql, int qr){
	if(ql <= l && qr >= r)
		return z[k].sum;
	push_down(k, l, r);
	int mid = l + r >> 1;
	ll ret = 0;
	if(ql <= mid) ret += query(ls, l, mid, ql, qr);
	if(qr > mid) ret += query(rs, mid + 1, r, ql, qr);
	return ret;	
}
void dfs1(int u, int fa){
	dep[u] = dep[fa] + 1;
	siz[u] = 1;
	f[u][0] = fa;
	for(int i = 1; i <= 23; ++i)
		f[u][i] = f[f[u][i - 1]][i - 1];	
	for(auto v : G[u]){
		if(v == fa) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		if(siz[v] > siz[son[u]]) son[u] = v;	
	}
}
void dfs2(int u, int tp){
	top[u] = tp;
	dfn[u] = ++tim;
	pos[tim] = u;
	if(son[u]) dfs2(son[u], tp);
	for(auto v : G[u]){
		if(v == f[u][0] || v == son[u]) continue;
		dfs2(v, v);
	}
}
int lca(int x, int y){
	while(top[x] != top[y]){
		if(dep[top[x]] < dep[top[y]])
			swap(x, y);
		x = f[top[x]][0];
	}
	return dep[x] < dep[y] ? x : y;
}
int get_son(int x, int y){
	if(dep[x] < dep[y])
		swap(x, y);
	for(int i = 23; i >= 0; --i)
		if(dep[f[x][i]] > dep[y])
			x = f[x][i];
	return x;	
}
void get_modify(int x, int y, int w){
	int l = lca(x, y), r = lca(x, root), z = lca(y, root);
	if(dep[r] > dep[l])	
		l = r;
	if(dep[z] > dep[l])
		l = z;
	if(l == root) modify(rot, 1, n, 1, n, w);
	else{
		if(lca(l, root) == l){
			modify(rot, 1, n, 1, n,  w);
			int s = get_son(l, root);
			modify(rot, 1, n, dfn[s], dfn[s] + siz[s] - 1, -w);
		}
		else
			modify(rot, 1, n, dfn[l], dfn[l] + siz[l] - 1, w);
	}
}
void get_ans(int x){
	if(x == root){
		ll ans = query(rot, 1, n, 1, n);
		cout << ans <<  '\n';
		return ;
	}
	else{
		if(lca(x, root) == x){
			ll ans = query(rot, 1, n, 1, n);
			int s = get_son(x, root);
			ans -= query(rot, 1, n, dfn[s], dfn[s] + siz[s] - 1);
			cout << ans << '\n';
			return ;
		}
		else{
			ll ans = query(rot, 1, n, dfn[x], dfn[x] + siz[x] - 1);
			cout << ans << '\n';
			return ;	
		}
	}
}
int main(){
	n = read(), m = read();
	for(int i = 1; i <= n; ++i)
		a[i] = read();
	for(int i = 1; i < n; ++i){
		int u, v;
		u = read(), v = read();
		G[u].push_back(v);
		G[v].push_back(u);	
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(rot, 1, n);
	while(m--){
		int op, l, r, x;
		op = read();
		if(op == 1)
			root = read();
		else if(op == 2){
			l = read(), r = read(), x = read();
			get_modify(l, r, x);
		}
		else{
			x = read();
			get_ans(x);	
		}
	}
	return 0;	
}

回复

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

正在加载回复...