Submission #153834

#TimeUsernameProblemLanguageResultExecution timeMemory
153834georgerapeanuFactories (JOI14_factories)C++11
100 / 100
7185 ms189552 KiB
#include "factories.h"
#include <vector>
#include <algorithm>

using namespace std;

const int NMAX = 5e5;
const int QMAX = 1e5;
const int LMAX = 19;
const long long inf = 1LL << 60;

int n,q;
vector< pair<int,long long> > graph[NMAX + 5];
vector< pair<int,long long> > graph2[NMAX + 5];
int lvl[NMAX + 5];
int father[LMAX + 1][NMAX + 5];
long long cost[NMAX + 5];

int len;
int pos[NMAX + 5];

int dsu[NMAX + 5];

long long best[NMAX + 5][2];
bool tp[NMAX + 5][2];

int fi_root(int nod){
    if(dsu[nod] == 0){
        return nod;
    }
    return dsu[nod] = fi_root(dsu[nod]);
}

inline long long get_cost(int w,int u){
    return cost[u] - cost[w];
}

void dfs(int nod,int tata,long long c){
    father[0][nod] = tata;
    cost[nod] = c;
    pos[nod] = ++len;
    lvl[nod] = 1 + lvl[tata];

    for(auto it:graph[nod]){
        if(it.first == tata){
            continue;
        }
        dfs(it.first,nod,c + it.second);
    }
}

int lca(int x,int y){
    if(lvl[x] > lvl[y]){
        swap(x,y);
    }

    int diff = lvl[y] - lvl[x];

    for(int h = LMAX;h >= 0;h--){
        if((diff >> h) & 1){
            y = father[h][y];
        }
    }

    if(x == y){
        return x;
    }

    for(int h = LMAX;h >= 0;h--){
        if(father[h][x] != father[h][y]){
            x = father[h][x];
            y = father[h][y];
        }
    }
    
    return father[0][x];
}

void dfs2(int nod,int tata,long long &ans){
    for(auto it:graph2[nod]){
        if(it.first == tata){
            continue;
        }
        dfs2(it.first,nod,ans);
        best[nod][0] = min(best[nod][0],best[it.first][0] + it.second);
        best[nod][1] = min(best[nod][1],best[it.first][1] + it.second);
    }
    if(tp[nod][0] == true){
        best[nod][0] = 0;
    }
    if(tp[nod][1] == true){
        best[nod][1] = 0;
    }

    ans = min(ans,best[nod][0] + best[nod][1]);
}

void res(int nod,int tata){
    dsu[nod] = 0;
    tp[nod][0] = tp[nod][1] = false;
    best[nod][0] = best[nod][1] = inf;

    for(auto it:graph2[nod]){
        if(it.first == tata){
            continue;
        }
        res(it.first,nod);
    }
    graph2[nod].clear();
}

void Init(int N, int A[], int B[], int D[]) {
    n = N;
    for(int i = 0;i < n - 1;i++){
        A[i]++;
        B[i]++;
        graph[A[i]].push_back({B[i],D[i]});
        graph[B[i]].push_back({A[i],D[i]});
    }

    dfs(1,0,0);

    for(int h = 1;h <= LMAX;h++){
        for(int i = 1;i <= n;i++){
            father[h][i] = father[h - 1][father[h - 1][i]];
        }
    }

    for(int i = 1;i <= n;i++){
        dsu[i] = 0;
        best[i][0] = best[i][1] = inf;
    }
}

long long Query(int S, int X[], int T, int Y[]) {

    vector<int> nodes;

    for(int i = 0;i < S;i++){
        X[i]++;
        nodes.push_back(X[i]);
        tp[X[i]][0] = true;
    }

    for(int i = 0;i < T;i++){
        Y[i]++;
        nodes.push_back(Y[i]);
        tp[Y[i]][1] = true;
    }

    sort(nodes.begin(),nodes.end(),[&](int a,int b){return pos[a] < pos[b];});

    vector<pair<int,pair<int,int> > > events;

    for(int i = 1;i < (int)nodes.size();i++){
        events.push_back(make_pair(lvl[lca(nodes[i - 1],nodes[i])],make_pair(nodes[i - 1],nodes[i])));
    }

    sort(events.begin(),events.end());
    reverse(events.begin(),events.end());

    int root = 0;
    for(auto it:events){
        it.second.first = fi_root(it.second.first);
        it.second.second = fi_root(it.second.second);
        int w = lca(it.second.first,it.second.second);

        if(it.second.first != w){
            long long c = get_cost(w,it.second.first);
            graph2[w].push_back({it.second.first,c});
            graph2[it.second.first].push_back({w,c});
            dsu[it.second.first] = w;
        }
        if(it.second.second != w){
            long long c = get_cost(w,it.second.second);
            graph2[w].push_back({it.second.second,c});
            graph2[it.second.second].push_back({w,c});
            dsu[it.second.second] = w;
        }

        root = w;
    }

    long long ans = inf;

    dfs2(root,0,ans);

    res(root,0);

    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...