新人求助,大常数树剖WA20求助
查看原帖
新人求助,大常数树剖WA20求助
430409
Coros_Trusds楼主2021/8/30 22:08

代码:

const int INF=(1<<29);

const int ma=200005;

struct Node
{
	int v;
	
	int nxt;
};

Node node[ma<<1];

int t[ma<<2],ans[ma<<2];

int head[ma],a[ma],wt[ma],id[ma],fa[ma],dep[ma],size[ma],son[ma],top[ma],mx[ma];

int n;

int idx,tot;

inline void add(int u,int v)
{
	node[++idx].v=v;
	
	node[idx].nxt=head[u];
	
	head[u]=idx;
}

inline int ls(int p)
{
	return p<<1;
}

inline int rs(int p)
{
	return p<<1|1;
}

inline void PushUp(int p)
{
	ans[p]=ans[ls(p)]+ans[rs(p)];
	
	mx[p]=max(mx[ls(p)],mx[rs(p)]);
}

inline void Build(int p,int l,int r)
{
	t[p]=0;
	
	if(l==r)
	{
		ans[p]=mx[p]=wt[l];
		
		return;
	}
	
	int mid=(l+r)>>1;
	
	Build(ls(p),l,mid);
	
	Build(rs(p),mid+1,r);
	
	PushUp(p);
}

inline void Updata(int nl,int nr,int l,int r,int p,int k)
{
	if(nl<=l && r<=nr)
	{
		ans[p]=mx[p]=k;
		
		return;
	}
	
	int mid=(l+r)>>1;
	
	if(nl<=mid)
	{
		Updata(nl,nr,l,mid,ls(p),k);
	}
	
	if(nr>mid)
	{
		Updata(nl,nr,mid+1,r,rs(p),k);
	}
	
	PushUp(p); 
}

inline int querymax(int nl,int nr,int l,int r,int p)
{
	if(nl<=l && r<=nr)
	{
		return mx[p];
	}
	
	int mid=(l+r)>>1,res=-INF;
	
	if(nl<=mid)
	{
		res=max(res,querymax(nl,nr,l,mid,ls(p)));
	}
	
	if(nr>mid)
	{
		res=max(res,querymax(nl,nr,mid+1,r,rs(p)));
	}
	
	return res;
}

inline int query(int nl,int nr,int l,int r,int p)
{
	if(nl<=l && r<=nr)
	{
		return ans[p];
	}
	
	int mid=(l+r)>>1,res=0;
	
	if(nl<=mid)
	{
		res+=query(nl,nr,l,mid,ls(p));
	}
	
	if(nr>mid)
	{
		res+=query(nl,nr,mid+1,r,rs(p));
	}
	
	return res;
}

inline void dfs1(int now,int fath,int depth)
{
	fa[now]=fath;
	
	size[now]=1;
	
	dep[now]=depth;
	
	int maxson=-1;
	
	for(register int i=head[now];i;i=node[i].nxt)
	{
		int v=node[i].v;
		
		if(v!=fath)
		{
			dfs1(v,now,depth+1);
			
			size[now]+=size[v];
			
			if(size[v]>maxson)
			{
				maxson=size[v];
				
				son[now]=v;
			}
		}
	}
}

inline void dfs2(int now,int topf)
{
	id[now]=++tot;
	
	top[now]=topf;
	
	wt[tot]=a[now];
	
	if(son[now]!=0)//非叶节点 
	{
		dfs2(son[now],topf);//遍历重儿子
		
		for(register int i=head[now];i;i=node[i].nxt)
		{
			int v=node[i].v;
			
			if(v!=fa[now] && v!=son[now])
			{
				dfs2(v,v);//轻儿子
			}
		} 
	}
}

inline int getmax(int x,int y)
{
	int res=-INF;
	
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			swap(x,y);
		}
		
		res=max(res,querymax(id[top[x]],id[x],1,n,1));
		
		x=fa[top[x]];
	}
	
	if(dep[x]>dep[y])
	{
		swap(x,y);
	}
	
	res=max(res,querymax(id[x],id[y],1,n,1));
	
	return res;
}

inline int getsum(int x,int y)
{
	int res=0,ans=0;
	
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			swap(x,y); 
		}
		
		res=query(id[top[x]],id[x],1,n,1);
		
		ans+=res;
		
		x=fa[top[x]];
	}
	
	if(dep[x]>dep[y])
	{
		swap(x,y);
	}
	
	res=query(id[x],id[y],1,n,1);
	
	ans+=res;
	
	return ans;
}

int main(void)
{
	scanf("%d",&n);
	
	for(register int i=1;i<=n-1;i++)
	{
		int u,v;
		
		scanf("%d%d",&u,&v);
		
		add(u,v);
		
		add(v,u); 
	}
	
	for(register int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	 
	int q;
	
	scanf("%d",&q);
	
	dfs1(1,0,1);
	
	dfs2(1,1);
	
	Build(1,1,n); 
	
	while(q--)
	{
		char opt[15];
		
		int x,y;
		
		cin>>opt;
		
		scanf("%d%d",&x,&y);
		
		if(opt[1]=='H')
		{
			Updata(x,x,1,n,1,y);
		}
		
		else if(opt[1]=='M')
		{
			printf("%d\n",getmax(x,y));
		}
		
		else
		{
			printf("%d\n",getsum(x,y));
		}
	}
	
	return 0;
}
2021/8/30 22:08
加载中...