社区讨论

调不过来,WA#5#6

P2590[ZJOI2008] 树的统计参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lo1d5qsk
此快照首次捕获于
2023/10/22 19:06
2 年前
此快照最后确认于
2023/11/02 19:50
2 年前
查看原帖
CPP
#include <bits/stdc++.h>//喵内~
#define re register//喵内~
#define int long long
using namespace std;//喵内~
typedef long long ll;
typedef long double ld;
const int N = 3e4 + 5;//喵内~要填数字哟~
inline int read(){
    int s = 0,f = 1;char c = getchar();
    while (!isdigit(c)){if (c == '-')f = -1;c = getchar();}
    while (isdigit(c)){s = (s<<3) + (s<<1) + (c ^ 48);c = getchar();}
    return s * f;
}//喵内~
int head[N],cnt,timer,dfn[N],rnk[N],top[N],size[N],son[N],dep[N],val[N],fa[N],h[N];
int n,m;
struct node{
	int v,next;
}tree[N << 1];
char s[10];
void add(int u,int v){
	tree[++cnt].next = head[u];
	tree[cnt].v = v;
	head[u] = cnt;
}
struct TernaryTree{
	struct node{
		int maxn,sum;
	}tree[N << 2];
	void pushup(int rt){
		tree[rt].sum = tree[rt<<1].sum + tree[rt << 1 | 1].sum;
		tree[rt].maxn = max(tree[rt << 1].maxn,tree[rt << 1 | 1].maxn);
	}
	void build(int rt,int l,int r){
		if (l == r){
			tree[rt].maxn = tree[rt].sum = val[rnk[l]];
			return ;
		}
		int mid = l + r >> 1;
		build(rt << 1,l,mid);
		build(rt << 1 | 1,mid+1,r);
		pushup(rt);
	}
	void change(int rt,int l,int r,int op,int t){
		if (l == r){
			tree[rt].sum = tree[rt].maxn = t;
			return ;
		}
		int mid = l + r >> 1;
		if (op <= mid)
		    change(rt << 1,l,mid,op,t);
		else change(rt << 1 | 1,mid + 1,r,op,t);
		pushup(rt);
	}
	int querymax(int rt,int l,int r,int x,int y){
		if (r < x || l > y)
		    return -1e9;
		if (l >= x && r <= y)
		    return tree[rt].maxn;
		int mid = l + r >> 1;
		return max(querymax(rt << 1,l,mid,x,y),querymax(rt << 1 | 1,mid+1,r,x,y));
	}
	int querysum(int rt,int l,int r,int x,int y){
		if (r < x || l > y)
		    return 0;
		if (l >= x && r <= y)
		    return tree[rt].sum;
		int mid = l + r >> 1;
		return querysum(rt << 1,l,mid,x,y) + querysum(rt << 1 | 1,mid + 1,r,x,y);
	}
}Tree;
void dfs1(int u,int father){
	dep[u] = dep[father] + 1;
	fa[u] = father;
	h[u] = -1,size[u] = 1;
	for (int i=head[u];i;i=tree[i].next){
		int v = tree[i].v;
		if (v == father)
		    continue;
		dfs1(v,u);
		size[u] += size[v];
		if (h[u] == -1 || size[v] > size[h[u]])
		    h[u] = v;
	}
}
void dfs2(int u,int t){
	top[u] = t;
	dfn[u] = ++timer;rnk[timer] = u;
	if (h[u] == -1)
	    return ;
	dfs2(h[u],t);
	for (int i=head[u];i;i=tree[i].next){
		int v = tree[i].v;
		if (v == fa[u] || v == h[u])
		    continue;
		dfs2(v,v);
	}
}
int querymax(int x,int y){
	int fx = top[x],fy = top[y];
	int res = -1e9;
	while (fx != fy){
		if (dep[fx] > dep[fy])
		    res = max(res,Tree.querymax(1,1,n,dfn[fx],x)),x = fa[fx];
		else 
		    res = max(res,Tree.querymax(1,1,n,dfn[fy],y)),y = fa[fy];
		fx = top[x],fy = top[y];
	}
	if (dep[x] > dep[y])
	    res = max(res,Tree.querymax(1,1,n,dfn[y],dfn[x]));
	else res = max(res,Tree.querymax(1,1,n,dfn[x],dfn[y]));
	return res;
}
int querysum(int x,int y){
	int fx = top[x],fy = top[y],res = 0;
	while (fx != fy){
		if (dep[fx] > dep[fy])
		    res += Tree.querysum(1,1,n,dfn[fx],dfn[x]),x = fa[fx];
		else res += Tree.querysum(1,1,n,dfn[fy],dfn[y]),y = fa[fy];
		fx = top[x],fy = top[y];
	}
	if (dep[x] > dep[y])
	    res += Tree.querysum(1,1,n,dfn[y],dfn[x]);
	else res += Tree.querysum(1,1,n,dfn[x],dfn[y]);
	return res;  
}
signed main(){
	n = read();
	for (int i=1,u,v;i<n;i++){
		u = read(); v = read();
		add(u,v);
		add(v,u);
	}
	for (int i=1;i<=n;i++)
	    val[i] = read();
	m = read();
    dfs1(1,0);
    dfs2(1,1);
    Tree.build(1,1,n);
    for (int i=1,u,v;i<=m;i++){
    	cin >> s;
    	u = read();v = read();
    	if (s[0] == 'C'){
    		Tree.change(1,1,n,dfn[u],v);
		} else if (s[0] == 'Q' && s[1] == 'M'){
			printf("%lld\n",querymax(u,v));
		} else printf("%lld\n",querysum(u,v));
	}
    return 0;
}//喵内~
/*
*/

回复

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

正在加载回复...