求助!!弱鸡写动态DP写挂了,只过得掉A类点QAQ
查看原帖
求助!!弱鸡写动态DP写挂了,只过得掉A类点QAQ
229446
ephemere楼主2020/11/4 20:41
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
const ll INF=1e10;
int n,m;
int te,v[N<<1],pre[N<<1],tail[N];
int tot,top[N],fa[N],siz[N],son[N],id[N],dfn[N],ed[N];
ll a[N],dp[N][2];
/*
0:随意
1:必选 
*/ 
struct node
{
	ll a[2][2];
	friend node operator+(node x,node y)
	{
		node z;
		for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
		z.a[i][j]=INF;

		for(int i=0;i<2;++i)
		for(int j=0;j<2;++j)
		for(int k=0;k<2;++k)
		z.a[i][j]=min(z.a[i][j],y.a[i][k]+x.a[k][j]);
		
		return z;
	}
}t[N<<2],val[N],las,now,ans;
/*
原版 是 val 
*/

inline void add(int x,int y)
{
	++te;v[te]=y;pre[te]=tail[x];tail[x]=te;
}

void dfs1(int x)
{
	siz[x]=1;
	dp[x][1]=a[x];
	
	for(int i=tail[x];i;i=pre[i])
	if(!siz[v[i]])
	{
		dfs1(v[i]);
		
		dp[x][0]+=dp[v[i]][1];
		dp[x][1]+=min(dp[v[i]][0],dp[v[i]][1]);
		
		fa[v[i]]=x;
		siz[x]+=siz[v[i]];
		if(siz[v[i]]>siz[son[x]]) son[x]=v[i];
	}
}

void dfs2(int x,int y)
{
	top[x]=y;
	
	++tot;
	dfn[x]=tot;id[tot]=x;ed[y]=tot;
	
	dp[x][0]-=dp[son[x]][1];
	dp[x][1]-=min(dp[son[x]][0],dp[son[x]][1]);
	
	val[x].a[0][0]=INF;
	val[x].a[1][0]=dp[x][0];
	val[x].a[0][1]=val[x].a[1][1]=dp[x][1];
	
	if(!son[x]) return;
	dfs2(son[x],y);
	for(int i=tail[x];i;i=pre[i])
	if(v[i]!=fa[x]&&v[i]!=son[x]) dfs2(v[i],v[i]);
}

void build(int l,int r,int p)
{
	if(l==r)
	{	
		t[p]=val[id[l]];
		return;	
	}
	
	int mid=(l+r)>>1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	
	t[p]=t[p<<1]+t[p<<1|1];
}


node ask(int l,int r,int x,int y,int p)
{
	if(l>=x&&r<=y) return t[p];
	
	int mid=(l+r)>>1;
	if(y<=mid) return ask(l,mid,x,y,p<<1);
	else if(x>mid) return ask(mid+1,r,x,y,p<<1|1);
	return ask(mid+1,r,x,y,p<<1|1)+ask(l,mid,x,y,p<<1); 
}

void change(int l,int r,int x,int p)
{
	if(l==r)
	{
		t[p]=val[id[l]];
		return;
	}
	
	int mid=(l+r)>>1;
	if(x<=mid) change(l,mid,x,p<<1);
	else change(mid+1,r,x,p<<1|1);
	
	t[p]=t[p<<1]+t[p<<1|1];
}
void update(int x,int tp)
{
	if(tp==0) val[x].a[0][1]=val[x].a[1][1]=INF;
	else if(tp==1) val[x].a[0][0]=val[x].a[1][0]=INF;
	else val[x].a[0][0]=INF,val[x].a[1][0]=dp[x][0],val[x].a[0][1]=val[x].a[1][1]=dp[x][1];
	
	while(x)
	{
		las=ask(1,n,dfn[top[x]],ed[top[x]],1);
		change(1,n,x,1);
		now=ask(1,n,dfn[top[x]],ed[top[x]],1);
		
		x=fa[top[x]];
		int las0=las.a[1][0],las1=las.a[1][1];
		int now0=now.a[1][0],now1=now.a[1][1];
		
		if(!x||(las0==now0&&las1==now1)) return;
		
		val[x].a[0][0]+=now1-las1;
		val[x].a[1][0]+=now1-las1;
		val[x].a[0][1]+=min(now1,now0)-min(las0,las1);
		val[x].a[1][1]+=min(now1,now0)-min(las0,las1);
	}
}
int main()
{
	char op[5];
	scanf("%d %d %s",&n,&m,&op);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
	for(int i=1,x,y;i<n;++i) scanf("%d %d",&x,&y),add(x,y),add(y,x);
	
	dfs1(1);dfs2(1,1);build(1,n,1);
	
	for(int i=1,a,b,x,y;i<=n;++i)
	{
		scanf("%d %d %d %d",&a,&x,&b,&y);
		
		if((a==b&&x!=y)||(!x&&!y&&(fa[a]==b||fa[b]==a))) {printf("-1\n");continue;}
		update(a,x);update(b,y);
		ans=ask(1,n,1,ed[1],1);
		printf("%lld\n",min(ans.a[1][0],ans.a[1][1]));
		update(a,2);update(b,2);
	}
}
2020/11/4 20:41
加载中...