树剖模板 0 pts 求助
查看原帖
树剖模板 0 pts 求助
688783
SilverLi楼主2023/5/8 19:48
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
int n,s,Q;
vector<int> g[N];
int d[N],fa[N],si[N],son[N];
int Index,dfn[N],top[N],val[N];
int a[N],t[N],ad1[N],ad2[N];
/*void add1(int p) {
	if(ad1[p]) {
		t[p<<1]+=ad1[p];
		t[p<<1|1]+=ad1[p];
		ad1[p<<1]+=ad1[p];
		ad1[p<<1|1]+=ad1[p];
		ad1[p]=0;
	}
}
void add2(int p) {
	if(ad2[p]) {
		t[p<<1]=ad2[p];
		t[p<<1|1]=ad2[p];
		ad2[p<<1]=ad2[p];
		ad2[p<<1|1]=ad2[p];
		ad2[p]=0;
		ad1[p<<1]=ad1[p<<1|1]=0;
	}
}
void down(int p) {add2(p),add1(p);}*/
void build(int l,int r,int p) {
	if(l==r) {	t[p]=a[l];	return;	}
	int m=l+r>>1;
	build(l,m,p<<1);build(m+1,r,p<<1|1);
	t[p]=t[p<<1]+t[p<<1|1];
}
/*void ADD(int l,int r,int S,int T,int p,int ch) {
	if(l>=S&&r<=T) {
		t[p]+=ch,ad1[p]+=ch;
		return;
	}
	int m=l+r>>1;
	down(p);
	if(S<=m)	ADD(l,m,S,T,p<<1,ch);
	if(T>m)	ADD(m+1,r,S,T,p<<1|1,ch);
	t[p]=t[p<<1]+t[p<<1|1];
	return;
}*/
void COVERONE(int l,int r,int X,int p,int ch) {
	if(l==r) {
		t[p]=ch;
		//ad2[p]=ch,
		//ad1[p]=0;
		return;
	}
	int m=l+r>>1;
	//down(p);
	if(X<=m)	COVERONE(l,m,X,p<<1,ch);
	if(X>m)	COVERONE(m+1,r,X,p<<1|1,ch);
	t[p]=t[p<<1]+t[p<<1|1];
	return;
}
/*void COVER(int l,int r,int S,int T,int p,int ch) {
	if(l>=S&&r<=T) {
		t[p]=ch,
		ad2[p]=ch,
		ad1[p]=0;
		return;
	}
	int m=l+r>>1;
	down(p);
	if(S<=m)	COVER(l,m,S,T,p<<1,ch);
	if(T>m)	COVER(m+1,r,S,T,p<<1|1,ch);
	t[p]=t[p<<1]+t[p<<1|1];
	return;
}*/
int ANS(int l,int r,int S,int T,int p) {
	if(l>=S&&r<=T)	return t[p];
	int m=l+r>>1,sum=0;
	//down(p);
	if(S<=m)	sum=ANS(l,m,S,T,p<<1);
	if(T>m)	sum+=ANS(m+1,r,S,T,p<<1|1);
	return sum;
}
void dfs1(int u,int ft) {
	d[u]=d[ft]+1,fa[u]=ft,
	si[u]=1;
	int mx=0;
	for(int i:g[u])
		if(i!=ft) {
			dfs1(i,u);
			si[u]+=si[i];
			if(si[i]>mx)	son[u]=i,mx=si[i];
		}
}
void dfs2(int u,int toop) {
	top[u]=toop;
	dfn[u]=++Index,a[Index]=val[u];
	if(!son[u])	return;
	dfs2(son[u],toop);
	for(int i:g[u])
		if(i!=fa[u]&&i!=son[u])	dfs2(i,i);
}
/*inline void change(int p,int w) {
	int cur;
	if(dfn[U[p]]>dfn[V[p]])	cur=U[p];
	else	cur=V[p];
	COVER(1,n,dfn[cur],dfn[cur],1,w);
}*/
/*
inline void cover(int u,int v,int w) {
	while(top[u]!=top[v]) {
		if(d[top[u]]<d[top[v]])	swap(u,v);
		COVER(1,n,dfn[top[u]],dfn[u],1,w);
		u=fa[top[u]];
	}
	if(d[u]>d[v])	swap(u,v);
	COVER(1,n,dfn[u],dfn[v],1,w);
}
inline void add(int u,int v,int w) {
	while(top[u]!=top[v]) {
		if(d[top[u]]<d[top[v]])	swap(u,v);
		ADD(1,n,dfn[top[u]],dfn[u],1,w);
		u=fa[top[u]];
	}
	if(d[u]>d[v])	swap(u,v);
	ADD(1,n,dfn[u],dfn[v],1,w);
}*/
inline int ans(int u,int v) {
	int res=0;
	while(top[u]!=top[v]) {
		if(d[top[u]]<d[top[v]])	swap(u,v);
		res+=ANS(1,n,dfn[top[u]],dfn[u],1);
		u=fa[top[u]];
	}
	if(d[u]>d[v])	swap(u,v);
	res+=ANS(1,n,dfn[u],dfn[v],1);
	return res;
}
signed main() {
	cin>>n>>Q;
	for(int i=1;i<=n;++i)    cin>>val[i];
	for(int i=1;i<n;++i) {
		int u,v;	cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1,1),dfs2(1,1);
	build(1,n,1);
	while(Q--) {
		cin>>s;
		int u,v;    cin>>u>>v;
		if(s==1) {
			COVERONE(1,n,dfn[u],1,v);
		} else {
			cout<<ans(u,v)<<endl;
		}
	}
	return 0;
}
2023/5/8 19:48
加载中...