Submission #1335684

#TimeUsernameProblemLanguageResultExecution timeMemory
1335684aaaaaaaaHarmonija (COCI25_harmonija)C++20
110 / 110
1492 ms858684 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define all(x) x.begin(), x.end()
#define chmax(v, x) v = max(v, x)

const int mxN = 1e5 + 5;
const int INF = -1e18;
const int mxB = 20;
const int K = 2;

int col[mxN][2];
vector<int> adj[mxN];

struct Mat{
    array<array<int, 5>, 5> dp;
    Mat(){
        for(int i = 0; i < 5; ++i){
            for(int j = 0; j < 5; ++j){
                dp[i][j] = 0;
            }
        }
    }
    static Mat inf(){
        Mat m = Mat();
        for(int i = 0; i < 5; ++i){
            for(int j = 0; j < 5; ++j){
                m.dp[i][j] = INF;
            }
        }
        return m;
    }
    Mat merge(Mat &other){
        Mat nw = inf();
        for(int st = -2; st <= 2; ++st){
            for(int en = -2; en <= 2; ++en){
                for(int nen = -2; nen <= 2; ++nen){
                    chmax(nw.dp[st + K][nen + K], dp[st + K][en + K] + other.dp[en + K][nen + K]);
                }
            }
        }
        return nw;
    }
};

Mat up[mxN][mxB], down[mxN][mxB], cur[mxN];
int tp[mxN][mxB], dep[mxN];

void dfs(int u = 1, int par = 0){
    cur[u] = Mat::inf();
    for(int st = -2; st <= 1; ++st){
        cur[u].dp[st + K][st + 1 + K] = col[u][0];
    }
    for(int st = -1; st <= 2; ++st){
        cur[u].dp[st + K][st - 1 + K] = col[u][1];
    }
    tp[u][0] = par, up[u][0] = cur[par];
    down[u][0] = cur[u], dep[u] = dep[par] + 1;
    for(int j = 1; j < mxB; ++j){
        int v = tp[u][j - 1];
        tp[u][j] = tp[v][j - 1];
        up[u][j] = up[u][j - 1].merge(up[v][j - 1]);
        down[u][j] = down[v][j - 1].merge(down[u][j - 1]);
    }
    for(auto it : adj[u]){
        if(it ^ par) dfs(it, u);
    }
}
int kth(int u, int k){
    for(int i = mxB - 1; i >= 0; --i){
        if(k & (1 << i)) u = tp[u][i];
    }
    return u;
}

int lca(int u, int v){
    if(dep[u] < dep[v]) swap(u, v);
    u = kth(u, dep[u] - dep[v]);
    if(u == v) return u;
    for(int j = mxB - 1; j >= 0; --j){
        if(tp[u][j] ^ tp[v][j]) u = tp[u][j], v = tp[v][j];
    }
    return tp[u][0];
}
int query(int u, int v){
    int l = lca(u, v);
    Mat left = cur[u];
    for (int j=0; j<mxB; j++) if ((dep[u] - dep[l])>>j&1) {
        left = left.merge(up[u][j]);
        u = tp[u][j];
    }
    Mat right = Mat();

    for (int j=0; j<mxB; j++) if ((dep[v] - dep[l])>>j&1) {
        right = down[v][j].merge(right);
        v = tp[v][j];
    }
    Mat z = left.merge(right);
    return *max_element(all(z.dp[2]));
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);
    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; ++i){
        cin >> col[i][0];
    }
    for(int i = 1; i <= n; ++i){
        cin >> col[i][1];
    }
    for(int i = 1, u, v; i <= n - 1; ++i){
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs();
    while(q--){
        int u, v;
        cin >> u >> v;
        cout << query(u, v) << "\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...