记录编号 586551 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2018]保卫王国 最终得分 100
用户昵称 Gravatar┭┮﹏┭┮ 是否通过 通过
代码语言 C++ 运行时间 3.232 s
提交时间 2024-02-03 11:00:26 内存使用 36.71 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
//DDP
const int N = 2e5+10;
const ll inf = 1e10;
int n,m;
struct Matrix{
	ll a,b,c,d;
	Matrix operator * (Matrix x){
		Matrix y;
		y.a = min(a+x.a,b+x.c);
		y.b = min(a+x.b,b+x.d);
		y.c = min(c+x.a,d+x.c);
		y.d = min(c+x.b,d+x.d); 
		return y;
	}
}I,val[N<<2],G[N];

struct mad{
	int ver,nx,ed;
}e[N<<1];
ll hd[N],tot,a[N],cnt;
void add(int x,int y){
	tot++;
	e[tot].nx = hd[x],e[tot].ver = y,hd[x] = tot;
}

int size[N],son[N],fa[N],en[N];
ll dfn[N],rnk[N],top[N],f[N][2],g[N][2];
void dfs1(int x){
	size[x] = 1,f[x][1] = a[x],f[x][0] = 0;
	for(int i = hd[x];i;i = e[i].nx){
		int y = e[i].ver;
		if(y == fa[x])continue;
		fa[y] = x;dfs1(y);
		size[x] += size[y],f[x][1] += min(f[y][1],f[y][0]),f[x][0] += f[y][1];
		if(!son[x] || size[y] > size[son[x]])son[x] = y;
	}
}
void dfs2(int x,int t){
	dfn[x] = ++cnt,rnk[cnt] = x,top[x] = t;
	g[x][1] = a[x],g[x][0] = 0;
	if(son[x])dfs2(son[x],t),en[x] = en[son[x]];
	else en[x] = x;
	for(int i = hd[x];i;i = e[i].nx){
		int y = e[i].ver;
		if(y == fa[x] || y == son[x])continue;
		dfs2(y,y);
		g[x][1] += min(f[y][1],f[y][0]),g[x][0] += f[y][1];
	}
}

struct segtree{
	void pushup(int p){
		val[p] = val[p<<1|1] * val[p<<1];
	}
	void build(int p,int l,int r){
		if(l == r){
			val[p] = G[rnk[l]]; 
			return;
		}
//		cout<<p<<' '<<l<<' '<<r<<endl;
		int mid = l + r >> 1;
		build(p<<1,l,mid),build(p<<1|1,mid+1,r);
		pushup(p);
	}
	void modify(int p,int l,int r,int x){
		if(l == r)return val[p] = G[rnk[l]],void();
		int mid = l + r >> 1;
		if(x <= mid)modify(p<<1,l,mid,x);
		else modify(p<<1|1,mid+1,r,x);
		pushup(p);
	}
	Matrix ask(int p,int l,int r,int L,int R){
		if(L <= l && r <= R)return val[p];
		int mid = l + r >> 1;
		if(R <= mid)return ask(p<<1,l,mid,L,R);
		else if(L > mid)return ask(p<<1|1,mid+1,r,L,R);
		else return ask(p<<1|1,mid+1,r,L,R) * ask(p<<1,l,mid,L,R); 
	}
}T;
void update(int x){
	G[x].b = G[x].d = g[x][1],G[x].a = inf,G[x].c = g[x][0]; 
}
ll cal(int x,ll z){
	g[x][1] += z;
	while(top[x] != 1){
		int fx = top[x],ff = fa[fx];
		Matrix s1 = I * T.ask(1,1,n,dfn[fx],dfn[en[fx]]);
		update(x),T.modify(1,1,n,dfn[x]);
		Matrix s2 = I * T.ask(1,1,n,dfn[fx],dfn[en[fx]]);
		g[ff][1] += min(s2.a,s2.b) - min(s1.a,s1.b);
		g[ff][0] += s2.b - s1.b;
		x = ff;
	}
	update(x),T.modify(1,1,n,dfn[x]);
	Matrix s = I * T.ask(1,1,n,1,dfn[en[1]]);
	return min(s.a,s.b);
}
void solve(int x,int y,int v1,int v2){
	if(!v1 && !v2 && (fa[x] == y || fa[y] == x)){printf("-1\n");return;}
	ll ans = 0;
	cal(x,v1?-inf:inf);
	ans = cal(y,v2?-inf:inf);
	if(v1)ans += inf;if(v2)ans += inf; 
	printf("%lld\n",ans);
	cal(x,v1?inf:-inf),cal(y,v2?inf:-inf);
}
int main(){
	freopen("2018defense.in","r",stdin);
	freopen("2018defense.out","w",stdout);
	scanf("%d%d",&n,&m);
	char c[10];cin>>c;
	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);
	dfs2(1,1);
	for(int i = 1;i <= n;i++)update(i);
	T.build(1,1,n);
	for(int i = 1;i <= m;i++){
		int x,y,v1,v2;
		scanf("%d%d%d%d",&x,&v1,&y,&v2);
		solve(x,y,v1,v2);
	}
	

	return 0;
	
}