Submission #1334010

#TimeUsernameProblemLanguageResultExecution timeMemory
1334010JuanJLHarmonija (COCI25_harmonija)C++20
87 / 110
2599 ms116480 KiB
#include <bits/stdc++.h>

#define fst first
#define snd second
#define pb push_back
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(),x.end()
#define forn(i,a,b) for(int i = a; i<b; i++)
#define mset(a,v) memset(a,v,sizeof(a))
#define FIN ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

using namespace std;
typedef long long ll;

#ifdef D
	#define debug(x) cout << x
#else 
	#define debug(x) //nothing
#endif

const int MAXN = 200000+5;

ll n,q; 
pair<ll,ll> qu[MAXN];

ll res[MAXN];
ll red[MAXN];
ll blue[MAXN];

ll subsz[MAXN];
ll isrem[MAXN];
vector<ll> adj[MAXN];

ll subtree_sz(ll nd, ll p){
	//cout<<nd<<" "<<p<<'\n';
	subsz[nd]=1;
	for(auto i:adj[nd]) if(i!=p && !isrem[i]){
		subsz[nd]+=subtree_sz(i,nd);
	}
	return subsz[nd];
}

ll get_centroid(ll nd , ll p, ll sztotal){
	//cout<<nd<<" "<<p<<'\n';
	for(auto i:adj[nd]) if(i!=p && !isrem[i]){
		if(subsz[i]*2>sztotal) return get_centroid(i,nd,sztotal);
	}

	return nd;
}

/////////////////////

const int MAXS = 5;

#define INF ((ll)99999999999999999)

ll dp1[MAXN][MAXS][MAXS][MAXS];
//ll dp2[MAXN][MAXS][MAXS];
ll myp[MAXN];
ll myr[MAXN];
ll state[MAXN];
ll actualstate;

void dfs(ll nd, ll p, ll centroid, ll round){
	myp[nd]=p;
	myr[nd]=round;
	state[nd]=actualstate;
	forn(i,0,5) forn(j,0,5) dp1[nd][i][j][0]=dp1[nd][i][j][1]=-INF;
	ll aux = 1;
	for(auto i:adj[nd]) if(i!=p && !isrem[i]){
		if(nd==centroid) dfs(i,nd,centroid,round+aux), aux++;
		else{
			dfs(i,nd,centroid,round);
		}
	}
}

ll f1(ll x, ll y, ll z,ll type, ll centroid){
	ll &res= dp1[x][y][z][type];
	if(res!=-INF) return res;

	if(type==0){
		if(x==centroid && y==z) return 0;
		if(x==centroid) return -INF;
	}else{
		if(x==centroid){
			res=-INF;
			if(y-1>=0 && y-1==z) res = max( res , red[x]);
			if(y+1<5 && y+1==z) res= max( res, blue[x]);
			return res;
		}
	}


	res = -INF;
	if(type==0){
		if(y+1<5) res = max(res, f1(myp[x],y+1,z,type,centroid)+red[x]);
		if(y-1>=0) res= max(res, f1(myp[x],y-1,z,type,centroid)+blue[x]);
	}else{
		if(y+1<5) res = max(res, f1(myp[x],y+1,z,type,centroid)+blue[x]);
		if(y-1>=0) res= max(res, f1(myp[x],y-1,z,type,centroid)+red[x]);		
	}
	return res;
}

////////////////////


void centroid_decomp(ll nd = 0){
	ll centroid = get_centroid(nd,-1,subtree_sz(nd,-1));

	isrem[centroid]=true;

	///////////////

	debug("New Centroid: "<<centroid<<'\n');
	actualstate++;
	//mset(myp,-1);
	//mset(myr,-1);
	dfs(centroid,-1,centroid,0);
	/*forn(i,0,n) if(myp[i]!=-1){
		forn(j,0,5){
			forn(k,0,5){
				f1(i,j,k,centroid);		
			}
		}
	}*/
	//forn(i,0,n) forn(j,0,5) forn(k,0,5) dp1[i][j][k][1]=dp1[i][j][k][0]=-INF;
	forn(i,0,q) if(res[i]==-INF){
		ll a = qu[i].fst;
		ll b = qu[i].snd;

		ll best = -INF;
		//cout<<" "<<myr[a]<<" "<<myr[b]<<'\n';
		if(myr[a]!=myr[b] && state[a]==actualstate && state[b]==actualstate){
			forn(j,0,5){
				forn(k,0,5){
					debug("Probando "<<a<<" "<<2<<" "<<k<<" = "<<f1(a,2,k,0,centroid)<<" y "<<b<<" "<<j<<" "<<k<<" = "<<f1(b,j,k,1,centroid)<<'\n');
					best=max(best,f1(a,2,k,0,centroid)+f1(b,j,k,1,centroid));
				}
			}
		}
		res[i]=best;
	}
	
	
	///////////////

	for(auto i:adj[centroid]) if(!isrem[i]){
		centroid_decomp(i);
	}
}


int main(){ FIN;
	mset(state,-1);
	cin>>n>>q;

	forn(i,0,n) cin>>red[i];
	forn(i,0,n) cin>>blue[i];

	ll u,v; 
	forn(i,0,n-1){
		cin>>u>>v; u--; v--;
		adj[u].pb(v);
		adj[v].pb(u);
	}

	forn(i,0,q){
		cin>>qu[i].fst>>qu[i].snd; qu[i].fst--; qu[i].snd--;
		res[i]=-INF;
		if(qu[i].fst==qu[i].snd) res[i]=max(red[qu[i].fst], blue[qu[i].snd]);
	}
	
	centroid_decomp();

	forn(i,0,q) cout<<res[i]<<'\n';
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...