救救孩子吧,84pts树剖,第十个点调不了一点
查看原帖
救救孩子吧,84pts树剖,第十个点调不了一点
739552
mygr楼主2023/11/8 22:33
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Max=5e5+5,inf=0x7fffffff;
int n,m;
struct edge{
	int to,next;
}p[Max*4];
string in;
int head[Max],idx=0,tot=0,sum=0;
int torank[Max],totree[Max];
struct infor{
	int w,dfn,top,hs,dep,size,fa,down;
}g[Max];

struct tree{
	int l,r,nl,nr,dp[2][2];
}t[Max*4];

struct dps{
	int dp[2][2];
	dps()
	{
		dp[0][0]=dp[0][1]=dp[1][0]=dp[1][1]=0;
	}
	dps(int n00,int n01,int n10,int n11)
	{
		dp[0][0]=n00;
		dp[0][1]=n01;
		dp[1][0]=n10;
		dp[1][1]=n11;
	}
}last[Max];

stack<pair<int,dps> > into;
int root[Max],cnt=0;
void pushup(int now)
{
	t[now].dp[0][0]=t[t[now].l].dp[0][0]+t[t[now].r].dp[0][0];
	t[now].dp[0][0]=max(t[now].dp[0][0] , t[t[now].l].dp[0][0]+t[t[now].r].dp[1][0]);
	t[now].dp[0][0]=max(t[now].dp[0][0] , t[t[now].l].dp[0][1]+t[t[now].r].dp[0][0]);
	
	t[now].dp[0][1]=t[t[now].l].dp[0][0]+t[t[now].r].dp[0][1];
	t[now].dp[0][1]=max(t[now].dp[0][1] , t[t[now].l].dp[0][0]+t[t[now].r].dp[1][1]);
	t[now].dp[0][1]=max(t[now].dp[0][1] , t[t[now].l].dp[0][1]+t[t[now].r].dp[0][1]);
	
 	t[now].dp[1][0]=t[t[now].l].dp[1][0]+t[t[now].r].dp[0][0];
	t[now].dp[1][0]=max(t[now].dp[1][0] , t[t[now].l].dp[1][0]+t[t[now].r].dp[1][0]);
	t[now].dp[1][0]=max(t[now].dp[1][0] , t[t[now].l].dp[1][1]+t[t[now].r].dp[0][0]);
	
	t[now].dp[1][1]=t[t[now].l].dp[1][0]+t[t[now].r].dp[0][1];
	t[now].dp[1][1]=max(t[now].dp[1][1] , t[t[now].l].dp[1][1]+t[t[now].r].dp[0][1]);
	t[now].dp[1][1]=max(t[now].dp[1][1] , t[t[now].l].dp[1][0]+t[t[now].r].dp[1][1]);
}
void build(int now,int l,int r)
{
	t[now].nl=l;
	t[now].nr=r;
	if(l==r)
	{
		t[now].dp[0][0]=0;
		t[now].dp[1][1]=g[torank[l]].w;
		t[now].dp[0][1]=-inf*0x7ffff;
		t[now].dp[1][0]=-inf*0x7ffff;
		totree[torank[l]]=now;
		return ;
	}
	int mid=(l+r)>>1;
	t[now].l=++cnt;
	build(cnt,l,mid);
	t[now].r=++cnt;
	build(cnt,mid+1,r);
	pushup(now);
}
void update(int now,int loc,dps num)
{
	if(t[now].nl==t[now].nr)
	{
		into.push(make_pair(now,dps(t[now].dp[0][0],t[now].dp[0][1],t[now].dp[1][0],t[now].dp[1][1])));
		t[now].dp[0][0]+=num.dp[0][0];
		t[now].dp[0][1]+=num.dp[0][1];
		t[now].dp[1][0]+=num.dp[1][0];
		t[now].dp[1][1]+=num.dp[1][1];
		return ;
	}
	int mid=(t[now].nl+t[now].nr)>>1;
	if(loc<=mid)
		update(t[now].l,loc,num);
	else
		update(t[now].r,loc,num);
	into.push(make_pair(now,dps(t[now].dp[0][0],t[now].dp[0][1],t[now].dp[1][0],t[now].dp[1][1])));
	pushup(now);
}
void add(int u,int v)
{
	p[++idx].next=head[u];
	head[u]=idx;
	p[idx].to=v;
}
void dfs(int now,int from)
{
	g[now].size++;
	g[now].dep=g[from].dep+1;
	g[now].fa=from;
	for(int i=head[now];p[i].to;i=p[i].next)
	{
		if(p[i].to==from)
			continue;
		dfs(p[i].to,now);
		g[now].size+=g[p[i].to].size;
	}
}
void dfs2(int now,int from)
{
	g[now].dfn=++tot;
	torank[tot]=now;
	g[now].down=now;
	int Maxsize=0,to=0;
	for(int i=head[now];p[i].to;i=p[i].next)
	{
		if(p[i].to==from)
			continue;
		if(g[p[i].to].size>Maxsize)
		{
			Maxsize=g[p[i].to].size;
			to=p[i].to;
		}
	}
	if(to==0)
		return ;
	g[now].hs=to;
	g[to].top=g[now].top;
	dfs2(to,now);
	g[now].down=g[to].down;
	for(int i=head[now];p[i].to;i=p[i].next)
	{
		if(p[i].to==from or p[i].to==to)
			continue;
		g[p[i].to].top=p[i].to;
		dfs2(p[i].to,now);
	}
}
void dfs3(int now,int from)
{
	if(g[now].top==now)
	{
		root[now]=++cnt;
		build(cnt,g[now].dfn,g[g[now].down].dfn);
	}
	for(int i=head[now];p[i].to;i=p[i].next)
	{
		if(p[i].to==from)
			continue;
		dfs3(p[i].to,now);
		if(p[i].to!=g[now].hs)
		{
			int top=g[p[i].to].top,rot=root[top];
			dps to;
			to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
			to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
			update(root[g[now].top],g[now].dfn,to);
		}
	}
	
	if(g[now].top==now)
	{
		int top=g[now].top,rot=root[top];
		dps to;
		to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
		to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
		last[rot]=dps(to.dp[0][0],0,0,to.dp[1][1]);
	}
	return ;
}

void Update(int now)
{
	while(g[now].top!=1)
	{
		int top=g[now].top,rot=root[top];
		dps to=dps(-last[rot].dp[0][0] ,0 ,0 ,-last[rot].dp[1][1]);
		to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
		to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
		update(root[g[g[top].fa].top],g[g[top].fa].dfn,to);
		now=g[top].fa;
	}
}

signed main()
{
	scanf("%lld%lld",&n,&m);
	cin>>in;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&g[i].w);
		sum+=g[i].w;
	}
	int x,y;
	for(int i=1;i<n;i++)
	{
		scanf("%lld%lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs(1,1);
	g[1].top=1;
	dfs2(1,1);
	dfs3(1,1);
	while(!into.empty())
		into.pop();
	int a,op1,b,op2;
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld%lld",&a,&op1,&b,&op2);
		
		if((g[a].fa==b or g[b].fa==a )and op1==0 and op2==0)
		{
			printf("-1\n");
			continue;
		}
		
		
		if(op1==0)
			update(root[g[a].top],g[a].dfn,dps(0,0,0,inf));
		else
			update(root[g[a].top],g[a].dfn,dps(0,0,0,-inf));
		Update(g[a].top);
		
		if(op2==0)
			update(root[g[b].top],g[b].dfn,dps(0,0,0,inf));
		else
			update(root[g[b].top],g[b].dfn,dps(0,0,0,-inf));
		Update(g[b].top);
		
		int ans=t[1].dp[0][0];
		ans=max(ans,t[1].dp[0][1]);
		ans=max(ans,t[1].dp[1][0]);
		ans=max(ans,t[1].dp[1][1]);
		if(op1==0)
			ans-=inf;
		if(op2==0)
			ans-=inf;
		while(sum-ans<0)
			ans-=inf;
		printf("%lld\n",sum-ans);
		
		while(!into.empty())
		{
			int now=into.top().first;
			dps to=into.top().second;
			into.pop();
			t[now].dp[0][0]=to.dp[0][0];
			t[now].dp[0][1]=to.dp[0][1];
			t[now].dp[1][0]=to.dp[1][0];
			t[now].dp[1][1]=to.dp[1][1];
		}
	}
}
2023/11/8 22:33
加载中...