제출 #1336153

#제출 시각아이디문제언어결과실행 시간메모리
1336153JuanJLHarmonija (COCI25_harmonija)C++20
110 / 110
2252 ms135176 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;

queue<ll> cola;
set<pair<ll,ll>> querie[MAXN];

void dfs(ll nd, ll p, ll centroid, ll round){
	myp[nd]=p;
	myr[nd]=round;
	//cout<<nd<<" tam "<<SZ(querie[nd])<<'\n';
	if(SZ(querie[nd])>0) cola.push(nd);
	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);
	while(!cola.empty()) cola.pop();
	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;
	while(!cola.empty()){
		ll a = cola.front();
		cola.pop();
		
		debug("New nd "<<a<<'\n');	

		queue<pair<ll,pair<ll,ll>>> toerase;
		for(auto B:querie[a]) if(res[B.snd]==-INF){

			ll i = B.snd;
			ll b = B.fst;

			debug("- "<<b<<" "<<i<<'\n');
			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;
				
				toerase.push({a,B});
			}
			
			//toerase.push({b,{a,i}});
			
		}

		while(!toerase.empty()){
			ll c1 = toerase.front().fst; toerase.pop();
			pair<ll,ll> pp = toerase.front().snd;
			auto it = querie[c1].find(pp);
			if(it!=querie[c1].end()) querie[c1].erase(it);
		}
	}
	/*
	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]);
		else{
			querie[qu[i].fst].insert({qu[i].snd,i});
			//querie[qu[i].snd].insert({qu[i].fst,i});
		}
	}
	
	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...