76pts,WA 18 ~ 23求助
查看原帖
76pts,WA 18 ~ 23求助
609565
OtterZ楼主2024/10/24 17:03
#include<bits/stdc++.h>
using namespace std;
#define MX 400000000009ll
struct mat{
	long long v[2][2];
	mat(){
		v[0][0] = v[1][1] = 0;
		v[0][1] = v[1][0] = MX;
	}
}pm[100009],seg[400009];
inline mat mpt(){
	mat c = mat();
	c.v[1][1] = MX;
	c.v[0][1] = 0;
	return c;
} 
mat operator*(mat x,mat y){
	mat z;
	z.v[0][0] = min(x.v[0][0] + y.v[0][0],x.v[0][1] + y.v[1][0]);
	z.v[0][1] = min(x.v[0][0] + y.v[0][1],x.v[0][1] + y.v[1][1]);
	z.v[1][0] = min(x.v[1][0] + y.v[0][0],x.v[1][1] + y.v[1][0]);
	z.v[1][1] = min(x.v[1][0] + y.v[0][1],x.v[1][1] + y.v[1][1]);
	return z;
}
void change(int k,int l,int r,int pl,mat val){
	if(l == r){
		seg[k] = val;
		return;
	}
	int m = (l + r) >> 1;
	if(m < pl)
		change((k << 1) | 1,m + 1,r,pl,val);
	else
		change((k << 1),l,m,pl,val);
	seg[k] = seg[(k << 1) | 1] * seg[(k << 1)];
//	printf(" %d %d %lld %lld %lld %lld\n",l,r,seg[k].v[0][0],seg[k].v[0][1],seg[k].v[1][0],seg[k].v[1][1]);
}
mat query(int k,int l,int r,int lq,int rq){
	if(lq > r || rq < l)
		return mat();
	if(lq <= l && r <= rq){
	//	printf("%d %d %lld %lld %lld %lld\n",l,r,seg[k].v[0][0],seg[k].v[0][1],seg[k].v[1][0],seg[k].v[1][1]);
		return seg[k];
	}
	int m = (l + r) >> 1;
	return query((k << 1) | 1,m + 1,r,lq,rq) * query((k << 1),l,m,lq,rq);
}
int n,q,dfscnt,dfs[100009],top[100009],fa[100009],dep[100009],p[100009],dfsl[100009],sz[100009];
vector<int>e[100009];
long long sg[100009][2],dp[100009][2],tg[100009][2];
void srh1(int v){
	dep[v] = dep[fa[v]] + 1;
	sz[v] = 1;
	int p = 0;
	for(int i = 0; i < e[v].size(); i ++){
		if(e[v][i] == fa[v]){
			swap(e[v][i],e[v][e[v].size() - 1]);
			e[v].pop_back();
			if(i == e[v].size())
				break;
		}
		fa[e[v][i]] = v;
		srh1(e[v][i]);
		sz[v] += sz[e[v][i]];
		if(sz[e[v][i]] > sz[e[v][p]])
			p = i;
	}
	if(e[v].size() > 0)
		swap(e[v][p],e[v][0]);
}
void srh2(int v){
	dfs[v] = ++dfscnt;
	dfsl[v] = dfs[v];
	dp[v][1] = sg[v][1] = p[v];
	if(e[v].size() > 0){
		//printf("%d %d\n",v,dfsl[v]);
		top[e[v][0]] = top[v];
		srh2(e[v][0]);
		dfsl[v] = dfsl[e[v][0]];
		dp[v][0] += dp[e[v][0]][1];
		dp[v][1] += min(dp[e[v][0]][1],dp[e[v][0]][0]);
		for(int i = 1; i < e[v].size(); i ++){
			top[e[v][i]] = e[v][i];
			srh2(e[v][i]);
			sg[v][0] = sg[v][0] + dp[e[v][i]][1];
			sg[v][1] = sg[v][1] + min(dp[e[v][i]][0],dp[e[v][i]][1]);
			dp[v][0] = dp[v][0] + dp[e[v][i]][1];
			dp[v][1] = dp[v][1] + min(dp[e[v][i]][0],dp[e[v][i]][1]);
		}
	}
	pm[v].v[0][0] = MX;
	pm[v].v[1][0] = sg[v][0];
	pm[v].v[0][1] = sg[v][1];
	pm[v].v[1][1] = sg[v][1];
	tg[v][0] = sg[v][0];
	tg[v][1] = sg[v][1];
//	printf("%d %d %d\n",v,sg[v][0],sg[v][1]);
	change(1,1,n,dfs[v],pm[v]);
}
void p_change(int v,mat val){
	while(true){
		int o = top[v];
		if(o == 1){
			change(1,1,n,dfs[v],val);
			break;
		}
		else{
			mat m = mpt() * query(1,1,n,dfs[o],dfsl[o]);
			tg[fa[o]][0] -= m.v[0][1];
			tg[fa[o]][1] -= min(m.v[0][0],m.v[0][1]);
			change(1,1,n,dfs[v],val);
			m = mpt() * query(1,1,n,dfs[o],dfsl[o]);
			tg[fa[o]][0] += m.v[0][1];
			tg[fa[o]][1] += min(m.v[0][0],m.v[0][1]);
			val.v[0][0] = MX;
			val.v[1][0] = tg[fa[o]][0];
			val.v[0][1] = val.v[1][1] = tg[fa[o]][1];
			v = fa[o];
		}
	}
}
int main(){
	//freopen("ios.in","r",stdin);
	//freopen("ios.out","w",stdout);
	scanf("%d %d",&n,&q);
	scanf(" %*s");
	for(int i = 1; i <= n; i ++){
		scanf("%d",&p[i]);
	}
	for(int i = 1; i < n; i ++){
		int u,v;
		scanf("%d %d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	srh1(1);
	top[1] = 1;
	srh2(1);
	for(int i = 1; i <= q; i ++){
		int a,x,b,y;
		scanf("%d %d %d %d",&a,&x,&b,&y);
		if(dep[a] < dep[b]){
			swap(a,b);
			swap(x,y);
		}
		if(fa[a] == b && x == 0 && y == 0){
			puts("-1");
		}
		else{
			mat m = pm[a];
			m.v[0][1] = (x == 1) ? sg[a][1] - MX - p[a] : sg[a][1] + MX - p[a];
			m.v[1][1] = (x == 1) ? sg[a][1] - MX - p[a] : sg[a][1] + MX - p[a];
			p_change(a,m);
			m = pm[b];
			m.v[0][1] = (y == 1) ? sg[b][1] - MX - p[b] : sg[b][1] + MX - p[b];
			m.v[1][1] = (y == 1) ? sg[b][1] - MX - p[b] : sg[b][1] + MX - p[b];
			p_change(b,m);
			//continue;
			m = mpt() * query(1,1,n,dfs[1],dfsl[1]);
			printf("%lld\n",min(m.v[0][0],m.v[0][1]) + (x + y) * MX + x * p[a] + y * p[b]);
			p_change(a,pm[a]);
			p_change(b,pm[b]); 
		}
	}
	return 0;
}
2024/10/24 17:03
加载中...