Submission #1332632

#TimeUsernameProblemLanguageResultExecution timeMemory
1332632JuanJLHarmonija (COCI25_harmonija)C++20
0 / 110
17 ms17860 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;

const int MAXN = 200000+5;

ll n,q;
ll red[MAXN];
ll blue[MAXN];

bool vis[MAXN];
bool block[MAXN];
ll cnt[MAXN];

vector<ll> adj[MAXN];


ll Find(ll nd, ll p, ll ori){
    for(auto i:adj[nd]) if(i!=p && !block[i]){
        if(cnt[i]*2>cnt[ori]){
            return Find(i,nd,ori);
        }
    }
    return nd;
}
void dfs(ll nd, ll p){
    vis[nd]=true;
    if(block[nd]) return;
    cnt[nd]=1;
    for(auto i:adj[nd]) if(i!=p){
        dfs(i,nd);
        cnt[nd]+=cnt[i];
    }
}

ll myround[MAXN];
ll dp[MAXN][10];
ll cen;

// diferencia red-blue
/*
0=-2
1=-1
2=0
3=1
4=2
*/
vector<ll> dif = {-2,-1,0,1,2};

void expand(ll nd, ll p, ll round){
    //cout<<"expand to "<<nd<<'\n';
    myround[nd]=round;
    forn(t, 0, 5){
        if(t-1>=0) dp[nd][t]=max( dp[nd][t] , dp[p][t-1]+red[nd] );
        if(t+1<5)  dp[nd][t]=max( dp[nd][t] , dp[p][t+1]+blue[nd] );
        //cout<<"dp "<<t<<" "<<dp[nd][t]<<'\n';
    } 

    for(auto i:adj[nd]) if(i!=p && !block[i]){
        expand(i,nd,round);
    }
}

bool centroid(){
    mset(vis,false);
    ll nd = -1;
    forn(i,0,n) if(!vis[i] && !block[i]){
        nd=i;
        break;
    }

    if(nd==-1) return false;
    dfs(nd,-1);
    cen = Find(nd,-1,nd);
    block[cen]=true;

    mset(myround,-1);
    forn(i,0,MAXN) forn(j,0,5){
        dp[i][j]=-900000000000000000;
    }
    dp[cen][2]=0;

    ll aux = 0;
    for(auto i:adj[cen]) if(!block[i]){
        expand(i,cen,aux);
        aux++;
    }
    myround[cen]=aux+1;

    //cout<<"Nuevo centroide : "<<cen<<"\n";
    return true;
}





int main(){
    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);
    }

    vector<pair<ll,ll>> qu(q); 
    forn(i,0,q) cin>>qu[i].fst>>qu[i].snd , qu[i].fst--,qu[i].snd--;

    vector<ll> res(q,-900000000000000000);
    while(centroid()){
        forn(i,0,q) if(qu[i].fst!=-1){
            u=qu[i].fst;
            v=qu[i].snd;
            if(u==v){
                qu[i].fst=-1;
                res[i]=max(res[i],max(red[u],blue[u]));
            }
            if(myround[v]!=-1 && myround[u]!=-1 && myround[u]!=myround[v]){
                
                forn(tu,0,5){
                    forn(tv,0,5){
                        ll rdif = dif[tu]+dif[tv];
                        
                        if(rdif+1<=3){
                            /*cout<<u<<" "<<tu<<" = "<<dp[u][tu]<<'\n';
                            cout<<v<<" "<<tv<<" = "<<dp[v][tv]<<'\n';
                            cout<<"agrega red "<<red[cen]<<'\n';*/
                            res[i]=max(res[i], dp[u][tu]+dp[v][tv]+red[cen]);
                        }
                        if(rdif-1<=3){
                            /*cout<<u<<" "<<tu<<" = "<<dp[u][tu]<<'\n';
                            cout<<v<<" "<<tv<<" = "<<dp[v][tv]<<'\n';
                            cout<<"agrega blue "<<blue[cen]<<'\n';*/
                            res[i]=max(res[i], dp[u][tu]+dp[v][tv]+blue[cen]);
                        }
                    }
                }
                //cout<<"Se responde querie "<<i<<'\n';
                qu[i].fst=-1;
            }
        }
    }

    for(auto i:res) cout<<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...