[xsy 1598][树剖+线段树/LCT]动态树

本文深入解析了如何使用树剖和线段树技术来解决动态DP问题,特别是在树形结构上的更新和查询操作。通过将树转换为链,利用重链分解技巧,实现了高效的动态维护和更新,适用于频繁更改点的权值并快速查询特定点的DP值场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有一个n个点的树
每次更改一个点的权值
维护这个树形dp
fu=min(pu,∑fson)f_u=min(p_u,\sum f_{son})fu=min(pu,fson)
动态询问u点的f值
解法:基本跟noip 2018 Day2T3一样,这里好好讲一讲动态dp的做法。
考虑树剖,线段树
线段树的l~r(前提在一条重链上)维护两个值sum1,sum2
在这里插入图片描述
我们维护如图所示的树的信息。
sum1表示叶子节点中只有r可以到达l时的最小值
sum2表示所有叶子节点均不可以到达l时的最小值
这里的“到达”含义结合dp递推式子理解
设左儿子为lsum1,lsum2
右儿子为rsum1,rsum2
那么sum1=lsum1+rsum1,sum2=min(lsum2,lsum1+rsum2)sum1=lsum1+rsum1,sum2=min(lsum2,lsum1+rsum2)sum1=lsum1+rsum1,sum2=min(lsum2,lsum1+rsum2)
查询子树u的f值直接查询区间
dfn[u],dfn[u所在重链的底端节点]
中途sum1,sum2的合并和刚才一样,答案就是最后的sum2
每次更改点的权值修改直接在线段树上修改
爬到重链顶端,可能会发现有一个节点的sum1要更改,循环改下去即可
其中可以用LCT维护
本质就是把树变成链来做(利用重链)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m;
#define Maxn 200010
ll val[Maxn];
int head[Maxn],v[Maxn<<1],nxt[Maxn<<1],tot=0;
int dfn[Maxn],fa[Maxn],siz[Maxn],son[Maxn],top[Maxn],lst[Maxn],dfk=0;
inline void add_edge(int s,int e){
	tot++;v[tot]=e;nxt[tot]=head[s];head[s]=tot;
	tot++;v[tot]=s;nxt[tot]=head[e];head[e]=tot;
}

void dfs1(int u,int f){
	fa[u]=f;siz[u]=1;
	for(int i=head[u];i;i=nxt[i])
	    if(v[i]^f){
	    	dfs1(v[i],u);
	    	siz[u]+=siz[v[i]];
	    	if(son[u]==-1||siz[v[i]]>siz[son[u]])son[u]=v[i];
		}
}
int dfs2(int u,int tp){
	top[u]=tp;dfn[u]=++dfk;
	if(son[u]==-1){
		lst[u]=u;
		return u;
	}
	lst[u]=dfs2(son[u],tp);
	for(int i=head[u];i;i=nxt[i])
	    if(v[i]!=fa[u]&&v[i]!=son[u])dfs2(v[i],v[i]);
	return lst[u];
}

struct Data{
	ll ans1,ans2;
}tree[Maxn<<2];
Data merge(Data node1,Data node2){
	Data res;
	res.ans1=node1.ans1+node2.ans1;
	res.ans2=min(node1.ans2,node1.ans1+node2.ans2);
	return res;
}
void push_up(int k){tree[k]=merge(tree[k<<1],tree[k<<1|1]);}
void Add(int k,int l,int r,int pos,ll ad1,ll ad2){
//	cout<<"pos "<<pos<<" "<<ad1<<" "<<ad2<<endl;
	if(l==r){
		tree[k].ans1+=ad1;
		tree[k].ans2+=ad2;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)Add(k<<1,l,mid,pos,ad1,ad2);
	else Add(k<<1|1,mid+1,r,pos,ad1,ad2);
	push_up(k);
}
Data Query(int k,int l,int r,int L,int R){
	if(l==L&&r==R)return tree[k];
	int mid=(l+r)>>1;
	if(R<=mid)return Query(k<<1,l,mid,L,R);
	else if(mid<L)return Query(k<<1|1,mid+1,r,L,R);
	else{
	    Data res1=Query(k<<1,l,mid,L,mid);
		Data res2=Query(k<<1|1,mid+1,r,mid+1,R);
		return merge(res1,res2);
	}
}

inline void Modify(int u,ll ad){
	ll tmp;
	ll pre=Query(1,1,dfk,dfn[top[u]],dfn[lst[u]]).ans2;
	Add(1,1,dfk,dfn[u],0,ad);
	while(top[u]!=1){
	//	cout<<"u "<<u<<endl;
		tmp=Query(1,1,dfk,dfn[top[u]],dfn[lst[u]]).ans2;
		ll AD=tmp-pre;
	//	cout<<"tmp pre "<<tmp<<" "<<pre<<endl;
		u=fa[top[u]];
		pre=Query(1,1,dfk,dfn[top[u]],dfn[lst[u]]).ans2;
		Add(1,1,dfk,dfn[u],AD,0);
	}
}

inline void rdint(int &x){
	x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
}
inline void rdll(ll &x){
	x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
}

char opt[5];

int main(){
	memset(son,-1,sizeof(son));
	rdint(n);
	for(register int i=1;i<=n;++i)rdll(val[i]);
	int s,e;
	for(register int i=1;i<n;++i){
		rdint(s);rdint(e);
		add_edge(s,e);
	}
	dfs1(1,0);
	dfs2(1,1);
//	cout<<"dfk "<<dfk<<endl;
//	for(register int i=1;i<=n;++i)cout<<"i "<<i<<" "<<son[i]<<" "<<top[i]<<" "<<lst[i]<<" "<<dfn[i]<<endl;
	for(register int i=1;i<=n;++i)Modify(i,val[i]);
	rdint(m);
	int x;ll y;
	while(m--){
		scanf("%s",opt);
		if(opt[0]=='Q'){
		    rdint(x);
			printf("%lld\n",Query(1,1,dfk,dfn[x],dfn[lst[x]]).ans2);		
		}else{
			rdint(x);rdll(y);
			Modify(x,y);
		}
	}
	return 0;
}/*
4
4 3 2 1
1 2
1 3
4 2
4
Q 1
Q 2
C 4 10
Q 1
*/
vue中折线图转Excel时导出来是ata:image/png;base64,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
最新发布
05-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值