MnZn求助 树剖+线段树 样例过了,交上去WA
查看原帖
MnZn求助 树剖+线段树 样例过了,交上去WA
371984
RC·阿柒楼主2022/4/26 09:51
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+1;
int n,q;
int w[N];
vector<int>e[N];
int dep[N],fa[N],hson[N],sz[N];
int dfn[N],val[N],top[N],cnt;
inline void dfs1(int u)
{
	dep[u]=dep[fa[u]]+1;
	sz[u]=1,hson[u]=-1;
	for(int v:e[u])
	{
		if(!dep[v])
		{
			fa[v]=u;
			dfs1(v);
			sz[u]+=sz[v];
			if(hson[u]==-1||sz[v]>sz[hson[u]])
				hson[u]=v;
		}
	}
}
inline void dfs2(int u,int Top)
{
	top[u]=Top;
	dfn[u]=++cnt;
	val[cnt]=u;
	if(hson[u]==-1)return;
	dfs2(hson[u],Top);
	for(int v:e[u])
	{
		if(v!=fa[u]&&v!=hson[u])
			dfs2(v,v);
	}
}

namespace SGT{
	struct Seg{
		int maxl,maxr,Max,sum,tag;bool flag;
		Seg(){maxl=maxr=Max=sum=tag=flag=0;}
	}seg[N<<2];
	#define mid ((l+r)>>1)
	#define ls (rt<<1)
	#define rs (rt<<1|1)
	inline Seg merge(Seg L,Seg R)
	{
		Seg res;
		res.sum=L.sum+R.sum;
		res.maxl=max(L.maxl,L.sum+R.maxl);
		res.maxr=max(R.maxr,R.sum+L.maxr);
		res.Max=max({L.Max,R.Max,L.maxr+R.maxl});
		res.flag=res.tag=0;
		return res;
	}
	inline void build(int rt,int l,int r)
	{
		if(l==r)
		{
			seg[rt].Max=seg[rt].maxl=seg[rt].maxr=max(0ll,w[val[l]]);
			seg[rt].sum=w[val[l]];
			return;
		}
		build(ls,l,mid);
		build(rs,mid+1,r);
		seg[rt]=merge(seg[ls],seg[rs]);
	}
	inline void push_down(int rt,int l,int r)
	{
		if(seg[rt].flag)
		{
			int x=seg[rt].tag;
			seg[ls].Max=seg[ls].maxl=seg[ls].maxr=max(0ll,x*(mid-l+1));
			seg[ls].sum=x*(mid-l+1);seg[ls].flag=1,seg[ls].tag=x;
			
			seg[rs].Max=seg[rs].maxl=seg[rs].maxr=max(0ll,x*(r-mid+2));
			seg[rs].sum=x*(r-mid+2);seg[rs].flag=1,seg[rs].tag=x;
			
			seg[rt].flag=seg[rt].tag=0;
		}
	}
	inline void Modify(int rt,int l,int r,int L,int R,int x)
	{
		if(L>r||R<l)return;
		if(L<=l&&r<=R)
		{
			seg[rt].Max=seg[rt].maxl=seg[rt].maxr=max(x*(r-l+1),0ll);
			seg[rt].sum=x*(r-l+1);seg[rt].flag=1,seg[rt].tag=x;
			return;
		}
		push_down(rt,l,r);
		Modify(ls,l,mid,L,R,x);
		Modify(rs,mid+1,r,L,R,x);
		seg[rt]=merge(seg[ls],seg[rs]);
	}
	inline Seg Query(int rt,int l,int r,int L,int R)
	{
		if(L<=l&&r<=R)
		{
			return seg[rt];
		}
		push_down(rt,l,r);
		Seg Ls,Rs;
		if(L<=mid)Ls=Query(ls,l,mid,L,R);
		if(R>mid)Rs=Query(rs,mid+1,r,L,R);
		return merge(Ls,Rs);
	}
}using namespace SGT;
inline void Rvs(int x,int y,int v)
{
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(dep[fx]<=dep[fy])
			swap(x,y),swap(fx,fy);
		Modify(1,1,n,dfn[fx],dfn[x],v);
		x=fa[fx],fx=top[x];
	}
	if(dfn[x]>dfn[y])
		swap(x,y);
	Modify(1,1,n,dfn[x],dfn[y],v);
}
inline Seg QSum(int x,int y)
{
	Seg L,R;
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(dep[fx]>=dep[fy])
			L=merge(Query(1,1,n,dfn[fx],dfn[x]),L),x=fa[fx],fx=top[x];
		else R=merge(Query(1,1,n,dfn[fy],dfn[y]),R),y=fa[fy],fy=top[y];
	}
	if(dfn[x]>dep[y])
		L=merge(Query(1,1,n,dfn[y],dfn[x]),L);
	else R=merge(Query(1,1,n,dfn[x],dfn[y]),R);
	swap(L.maxl,L.maxr);
	return merge(L,R);
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>w[i];
	for(int i=1;i<n;i++)
	{
		int u,v;cin>>u>>v;
		e[u].emplace_back(v);
		e[v].emplace_back(u);
	}
	dfs1(1);
	dfs2(1,1);
	build(1,1,n);
	cin>>q;
	while(q--)
	{
		int opt,a,b,c;
		cin>>opt>>a>>b;
		if(opt==1)
		{
			cout<<QSum(a,b).Max<<'\n';
		}
		else
		{
			cin>>c;
			Rvs(a,b,c);
		}
	}
	return 0;
}

2022/4/26 09:51
加载中...