WA求调
查看原帖
WA求调
793770
2021cyq楼主2023/7/3 21:46
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=200000+500,M=4*N;
struct node
{
	int sum,lmax,rmax,ans;
	int lazy;
}tree[4*N];
int fx,fy,fz;
int head[M],nex[M],to[M],son[M],siz[N],bz[N];
int dfn[N],tot,cnt,deep[N],fa[N];
int n,m;
int a[N],top[N];
void add(int x,int y)
{
	tot++;
	nex[tot]=head[x];
	head[x]=tot;
	to[tot]=y;
}
void dfs1(int x,int dep)
{
	bz[x]=1;
	deep[x]=dep;
	for(int i=head[x];i;i=nex[i])
	{
		int y=to[i];
		if(bz[y]==0)
		{
			fa[y]=x;
			dfs1(y,dep+1);
			siz[x]+=siz[y];
			if(siz[son[x]]<siz[y])son[x]=y;
		}
	}
	siz[x]++;
}
void dfs2(int x,int topp)
{
	bz[x]=1;
	cnt++;
	dfn[x]=cnt;
	top[x]=topp;
	if(!son[x])return ;
	dfs2(son[x],topp);
	for(int i=head[x];i;i=nex[i])
	{
		int y=to[i];
		if(bz[y]==0&&y!=son[x])dfs2(y,y);
	}
}
void change(int x)
{
	tree[x].sum=tree[x+x].sum+tree[x+x+1].sum;
	tree[x].ans=max(tree[x+x].ans,max(tree[x+x+1].ans,tree[x+x].rmax+tree[x+x+1].lmax));
	tree[x].lmax=max(tree[x+x].lmax,tree[x+x].sum+tree[x+x+1].lmax);
	tree[x].rmax=max(tree[x+x+1].rmax,tree[x+x+1].sum+tree[x+x].rmax);
}
void change1(int x,int l,int r,int z)
{
	tree[x].lazy=z;
	tree[x].sum=(r-l+1)*z;
	tree[x].lmax=tree[x].rmax=tree[x].ans=max(0,tree[x].sum);
}
void down(int x,int l,int r)
{
	int mid=(l+r)>>1;
	if(tree[x].lazy)
	{
		change1(x+x,l,mid,tree[x].lazy);
		change1(x+x+1,mid+1,r,tree[x].lazy);
	}
	tree[x].lazy=0;
}
void ch(int i,int l,int r)
{
	if(fx>r||l>fy)return ;
	if(fx<=l&&r<=fy)
	{
		change1(i,l,r,fz);
		return ;
	}
	int mid=(l+r)>>1;
	down(i,l,r);
	ch(i+i,l,mid);
	ch(i+i+1,mid+1,r);
	change(i);
}
node q(int i,int l,int r)
{
	if(fx>r||l>fy)return {0,0,0,0,0};
	if(fx<=l&&r<=fy)return tree[i];
	int mid=(l+r)>>1;down(i,l,r);
	node ans1=q(i+i,l,mid);
	node ans2=q(i+i+1,mid+1,r);
	node noww={0,0,0,0,0};
	noww.sum=ans1.sum+ans2.sum;
	noww.lmax=max(ans1.lmax,ans1.sum+ans2.lmax);
	noww.rmax=max(ans2.rmax,ans1.rmax+ans2.sum);
	noww.ans=max(ans1.ans,max(ans2.ans,ans1.rmax+ans2.lmax));
	change(i);
	return noww;
}
void changed(int x,int y)
{
	if(deep[x]<deep[y])swap(x,y);
	while(deep[top[x]]>=deep[y])
	{
		fx=dfn[top[x]],fy=dfn[x];
		ch(1,1,n);
		x=fa[top[x]];
	}
	if(deep[x]>=deep[y])
	{
		fx=dfn[y],fy=dfn[x];
		ch(1,1,n);
	}
}
node got(int x,int y)
{	
	node ans={0,0,0,0,0};
	if(deep[x]<deep[y])swap(x,y);
	while(deep[top[x]]>=deep[y])
	{
		fx=dfn[top[x]],fy=dfn[x];
		node now1=q(1,1,n);
		ans.sum+=now1.sum;
		ans.ans=max(ans.ans,max(now1.ans,now1.rmax+ans.lmax));
		ans.rmax=max(ans.rmax,ans.sum+now1.rmax);
		ans.lmax=max(ans.lmax+now1.sum,now1.lmax);
		x=fa[top[x]];
	}
	if(deep[x]>=deep[y])
	{
		fx=dfn[y],fy=dfn[x];
		node now1=q(1,1,n);
		ans.sum+=now1.sum;
		ans.ans=max(ans.ans,max(now1.ans,now1.rmax+ans.lmax));
		ans.rmax=max(ans.rmax,ans.sum+now1.rmax);
		ans.lmax=max(ans.lmax+now1.sum,now1.lmax);
	}
	return ans;
}
int LCA(int u,int v)
{
	while(top[u]!=top[v])
	{
		if(deep[top[u]]>deep[top[v]])u=fa[top[u]];
		else v=fa[top[v]];
	}
	if(deep[u]>deep[v])return v;
	else return u;
}
void getans(int x,int y)
{
	int lca=LCA(x,y),lca1,xx=x,yy=y;
	if(lca==x||lca==y)printf("%d\n",got(x,y).ans);
	else
	{
		while(deep[x]>deep[lca]+1)
		{
			if(deep[top[x]]>deep[lca])x=top[x];
			if(deep[fa[x]]>deep[lca])x=fa[x];
		}
		lca1=x;
		node ans1=got(lca,yy),ans2=got(xx,lca1);
		ans2.ans=max(ans2.ans,max(ans1.ans,ans2.lmax+ans1.lmax));
		printf("%d\n",ans2.ans);
	}
}
void changeans(int x,int y)
{
	int lca=LCA(x,y),lca1,xx=x,yy=y;
	if(lca==x||lca==y)changed(x,y);
	else
	{
		while(deep[x]>deep[lca]+1)
		{
			if(deep[top[x]]>deep[lca])x=top[x];
			if(deep[fa[x]]>deep[lca])x=fa[x];
		}
		lca1=x;
		changed(lca,yy),changed(xx,lca1);
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs1(1,1);
	memset(bz,0,sizeof(bz));
	dfs2(1,1);
	for(int i=1;i<=n;i++)
	{
		fx=fy=dfn[i];
		fz=a[i];
		ch(1,1,n);
	}
	scanf("%d",&m);
	while(m--)
	{
		int opt;
		int x,y,z;
		scanf("%d",&opt);
		if(opt==1)
		{
			scanf("%d%d",&x,&y);
			getans(x,y);
		}
		else
		{
			scanf("%d%d%d",&x,&y,&z);
			fz=z;
			changeans(x,y);
		}
	}
}

我的方法有点不一样,把x->y拆成x->lca,lca->y,再分别搞。

2023/7/3 21:46
加载中...