树连剖分,10分,求助!!!
查看原帖
树连剖分,10分,求助!!!
486001
Knighthood楼主2022/3/27 14:04
#include<bits/stdc++.h>
#define M 30003
#define N M<<1
#define E1(i) Edge(E[i].x,E[i].y)
#define E2(i) Edge(E[i].y,E[i].x)
#define INF INT_MAX/2
using namespace std;
int n,q,h[M],to[N],nex[N],num,pos,Q;
int prt[M],siz[M],son[M],dep[M],top[M],p[M],fp[M];
struct Node{
	int x,y,w;
}E[N];
struct Return{
	int Max,Sum;
};
struct Tree{
	int l,r,mx,sum;
	#define l(k) t[k].l
	#define r(k) t[k].r
	#define mx(k) t[k].mx
	#define s(k) t[k].sum
}t[M<<2];
void Edge(int a,int b){
	to[++num]=b;
	nex[num]=h[a];
	h[a]=num;
}
void Dfs_1(int u,int fa,int d){
	prt[u]=fa;
	siz[u]=1;
	dep[u]=d;
	for(int i=h[u];i;i=nex[i]){
		int v=to[i];
		if(v!=fa){
			Dfs_1(v,u,d+1);
			siz[u]+=siz[v];
			if(son[u]==-1||siz[v]>siz[son[u]])son[u]=v;
		}
	}
}
void Dfs_2(int u,int sp){
	top[u]=sp;
	p[u]=++pos;
	fp[p[u]]=u;
	if(son[u]!=-1)Dfs_2(son[u],sp);
	for(int i=h[u];i;i=nex[i]){
		int v=to[i];
		if(v!=son[u]&&v!=prt[u])Dfs_2(v,v);
	}
}
void Build(int k,int l,int r){
	l(k)=l,r(k)=r,mx(k)=INF;
	if(l==r){/*s(k)=mx(k)=E[fp[l]].w;*/return;}
	int mid=l+r>>1;
	Build(k*2,l,mid);Build(k*2+1,mid+1,r);
}
void Push_up(int k){
	mx(k)=max(mx(k*2),mx(k*2+1));
	s(k)=s(k*2)+s(k*2+1);
}
void Insert(int k,int x,int val){
	if(l(k)>x||r(k)<x)return;
	if(l(k)==r(k)){mx(k)=s(k)=val;return;}
	Insert(k*2,x,val);Insert(k*2+1,x,val);
	Push_up(k);
}
int Askmax(int k,int l,int r){
	if(l(k)>r||r(k)<l)return -INF;
	if(l<=l(k)&&r>=r(k))return mx(k);
	int ans=max(Askmax(k*2,l,r),Askmax(k*2+1,l,r));
	Push_up(k);
	return ans;
}
int Findmax(int u,int v){
	int f1=top[u],f2=top[v],tmp=0;
	while(f1!=f2){
		if(dep[f1]<dep[f2])swap(f1,f2),swap(u,v);
		tmp=max(tmp,Askmax(1,p[f1],p[u]));
		u=prt[f1];f1=top[u];
	}
	if(dep[u]>dep[v])swap(u,v);
	return max(tmp,Askmax(1,p[u],p[v]));
}
int Asksum(int k,int l,int r){
	if(l(k)>r||r(k)<l)return 0;
	if(l<=l(k)&&r>=r(k))return s(k);
	int ans=Asksum(k*2,l,r)+Asksum(k*2+1,l,r);
	Push_up(k);
	return ans;
}
int Findsum(int u,int v){
	int f1=top[u],f2=top[v],tmp=0;
	while(f1!=f2){
		if(dep[f1]<dep[f2])swap(f1,f2),swap(u,v);
		tmp+=Asksum(1,p[f1],p[u]);
		u=prt[f1];f1=top[u];
	}
	if(dep[u]>dep[v])swap(u,v);
	return tmp+Asksum(1,p[u],p[v]);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(NULL);cout.tie(NULL);
	cin>>n;
	for(int i=1;i<n;++i){
		cin>>E[i].x>>E[i].y;
		E1(i);E2(i);
	}
	for(int i=1;i<=n;++i)cin>>E[i].w;
	memset(son,-1,sizeof(son));
	Dfs_1(1,0,1);
	Dfs_2(1,1);
	Build(1,1,pos);
	for(int i=1;i<=n;++i)Insert(1,p[i],E[i].w);
	cin>>Q;
	while(Q--){
		string s;
		int l,r;
		cin>>s>>l>>r;
		if(s=="QMAX"){
			cout<<Findmax(l,r)<<'\n';
		}
		else if(s=="QSUM")cout<<Findsum(l,r)<<'\n';
		else Insert(1,p[l],r);
	}
	return 0;
}
2022/3/27 14:04
加载中...