蒟蒻刚学树剖,求条
查看原帖
蒟蒻刚学树剖,求条
1065071
Atserckcn楼主2024/5/30 22:08

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e4+5,inf=1e9+5;
int n,m,mid;
int w[MAXN],head[MAXN],x,y,cntedge;
int dep[MAXN],siz[MAXN],son[MAXN],fa[MAXN],dfn[MAXN],rink[MAXN],top[MAXN];//两次深搜所需信息 
string s;
int fx,fy;
int u,v,cnt,res;
inline void read(int &number)
{
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') number=-number;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		number=(number<<1)+(number<<3)+(ch-'0');
		ch=getchar();
	}
	return;
}
struct EDGE{
	int from,to,pre;
}edge[MAXN<<1];
void add(int from,int to)
{
	edge[++cntedge].from=from;
	edge[cntedge].to=to;
	edge[cntedge].pre=head[from];
	head[from]=cntedge;
	return;
}
void dfs1(int u,int ufa)
{
	dep[u]=dep[ufa]+1;
	for(int i=head[u];i;i=edge[i].pre)
	{
		if(edge[i].to==ufa) continue;
		fa[edge[i].to]=u;
		dfs1(edge[i].to,u);
		siz[u]+=siz[edge[i].to];
		if(siz[edge[i].to]>siz[son[u]]) son[u]=edge[i].to;
	}
	return;
}
void dfs2(int u,int t)
{
	top[u]=t;
	if(!son[u]) return;
	dfn[u]=++cnt;
	rink[cnt]=u;
	dfs2(son[u],t);
	for(int i=head[u];i;i=edge[i].pre)
		if(son[u]!=edge[i].to&&edge[i].to!=fa[u]) dfs2(edge[i].to,edge[i].to);//分成若干小树链 
	return;
}
struct NODE{
	int l,r,sum,maxn;//线段树 
}node[MAXN<<2];
void build(int l,int r,int p)
{
	node[p].l=l,node[p].r=r;
	if(l==r)
	{
		node[p].sum=node[p].maxn=w[rink[l]];
		return;
	}
	mid=(l+r)>>1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	node[p].sum=node[p<<1].sum+node[p<<1|1].sum;
	node[p].maxn=max(node[p<<1].maxn,node[p<<1|1].maxn);
	return;
}
void upd(int l,int r,int p,int t,int x)
{
	if(l==r)
	{
		node[p].maxn=node[p].sum=t;
		return;
	}
	mid=(l+r)>>1;
	if(x<=mid)
		upd(l,mid,p<<1,t,x);
	else upd(mid+1,r,p<<1|1,t,x);
	node[p].sum=node[p<<1].sum+node[p<<1|1].sum;
	node[p].maxn=max(node[p<<1].maxn,node[p<<1|1].maxn);
	return;
}
int q1(int l,int r,int p,int rl,int rr)
{
	if(l>rr||r<rl) return -inf;
	if(l<=rl&&r<=rr) return node[p].maxn;
	mid=(l+r)>>1;
	return max(q1(l,mid,p<<1,rl,rr),q1(mid+1,r,p<<1|1,rl,rr));
}
int q2(int l,int r,int p,int rl,int rr)
{
	if(l>rr||r<rl) return 0;
	if(rl<=l&&rr<=r) return node[p].sum;
	mid=(l+r)>>1;
	return q2(l,mid,p<<1,rl,rr)+q2(mid+1,r,p<<1|1,rl,rr);
}
int qmax(int x,int y)
{
	res=-inf,fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(dep[fx]>=dep[fy]) res=max(res,q1(1,n,1,dfn[fx],dfn[x])),x=fa[fx];
		else res=max(res,q1(1,n,1,dfn[fy],dfn[y])),y=fa[fy];
		fx=top[x];
		fy=top[y];
	}
	if(dfn[x]<dfn[y])
		res=max(res,q1(1,n,1,dfn[x],dfn[y]));
	else res=max(res,q1(1,n,1,dfn[y],dfn[x]));
	return res;
}
int qsum(int x,int y)
{
	res=0,fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(dep[x]>=dep[y]) res+=max(res,q2(1,n,1,dfn[fx],dfn[x]));
		else res+=max(res,q2(1,n,1,dfn[fy],dfn[y]));
		fx=top[x];
		fy=top[y];
	}
	return res;
}
int main(){
	read(n);
	for(int i=1;i<n;i++)
		read(x),read(y),add(x,y),add(y,x);
	for(int i=1;i<=n;i++)
		read(w[i]);
	dep[1]=1;
	build(1,n,1);
	dfs1(1,1);
	dfs2(1,1);
	read(m);
	while(m--)
	{
		cin >> s; 
		read(u),read(v);
		if(s.find("CHANGE")==0)
			upd(1,n,1,v,dfn[u]);
		else if(s.find("QMAX")==0)
			printf("%d\n",qmax(u,v));
		else printf("%d\n",qsum(u,v));
	}
	return 0;
}

只能说听取RE声一片……

2024/5/30 22:08
加载中...