Submission #387527

# Submission time Handle Problem Language Result Execution time Memory
387527 2021-04-08T18:39:34 Z aryan12 Factories (JOI14_factories) C++17
0 / 100
35 ms 26988 KB
#include "factories.h"
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 5e5 + 5;
vector<pair<int, int> > g[MAXN];
int Subtree[MAXN], lastCnt[MAXN], centroidParent[MAXN];
long long distFromRoot[MAXN], ans[MAXN];
bool isTaken[MAXN];
int DP[20][MAXN], depth[MAXN];
int cnt = 0;

void FindDist(int node, int par) {
    DP[0][node] = par;
    for(int i = 0; i < g[node].size(); i++) {
        if(g[node][i].first != par) {
            distFromRoot[g[node][i].first] = distFromRoot[node] + g[node][i].second;
            depth[g[node][i].first] = depth[node] + 1;
            FindDist(g[node][i].first, node);
        }
    }
}

int SubtreeDfs(int node, int par) {
    Subtree[node] = 1;
    for(int i = 0; i < g[node].size(); i++) {
        if(!isTaken[g[node][i].first] && !isTaken[node] && g[node][i].first != par) {
            Subtree[node] += SubtreeDfs(g[node][i].first, node);
        }
    }
    return Subtree[node];
}

int FindCentroid(int node, int par, int totalSize) {
    for(int i = 0; i < g[node].size(); i++) {
        if(!isTaken[g[node][i].first] && !isTaken[node] && g[node][i].first != par) {
            if(Subtree[g[node][i].first] > totalSize / 2) {
                return FindCentroid(g[node][i].first, node, totalSize);
            }
        }
    }
    return node;
}

void BuildCentroid(int centroid, int par) {
    int siz = SubtreeDfs(centroid, -1);
    centroid = FindCentroid(centroid, par, siz);
    isTaken[centroid] = true;
    if(par == -1)
        centroidParent[centroid] = centroid;
    else
        centroidParent[centroid] = par;
    for(int i = 0; i < g[centroid].size(); i++) {
        if(!isTaken[g[centroid][i].first]) {
            BuildCentroid(g[centroid][i].first, centroid);
        }
    }
}

void Init(int N, int A[], int B[], int D[]) {
    for(int i = 0; i < MAXN; i++) {
        isTaken[i] = false;
        Subtree[i] = 0;
        distFromRoot[i] = 0;
        centroidParent[i] = i;
        lastCnt[i] = 0;
        ans[i] = 1e15;
    }
    cnt = 0;
    for(int i = 0; i < N - 1; i++) {
        g[A[i]].push_back({B[i], D[i]});
        g[B[i]].push_back({A[i], D[i]});
    }
    distFromRoot[0] = 0;
    depth[0] = 0;
    FindDist(0, -1);
    BuildCentroid(0, -1);
    for(int i = 1; i < 20; i++) {
        for(int j = 0; j < N; j++) {
            if(DP[i - 1][j] == -1) {
                DP[i][j] = -1;
            }
            else {
                DP[i][j] = DP[i - 1][DP[i - 1][j]];
            }
        }
    }
    /*cout << "Centroid Parents\n";
    for(int i = 0; i < N; i++) {
        cout << centroidParent[i] << " ";
    }
    cout << "\n";
    cout << "distFromRoot\n";
    for(int i = 0; i < N; i++) {
        cout << distFromRoot[i] << " ";
    }
    cout << "\n";
    cout << "Normal parents\n";
    for(int i = 0; i < N; i++) {
        cout << DP[0][i] << " ";
    }
    cout << "\n";
    cout << "Binary lifting array\n";
    for(int i = 0; i < 20; i++) {
        for(int j = 0; j < N; j++) {
            cout << DP[i][j] << " ";
        }
        cout << "\n";
    }*/
}

int LCA(int x, int y) {
    if(depth[x] < depth[y])
        swap(x, y);
    int diff = depth[x] - depth[y];
    /*cout << "IN LCA\n";
    cout << "x = " << x << ", y = " << y << ", diff = " << diff << "\n";
    cout << "(1 << 2) = " << (1 << 2) << "\n";*/
    for(int i = 19; i >= 0; i--) {
        if(diff >= (1 << i)) {
            diff -= (1 << i);
            x = DP[i][x];
        }
    }
    //cout << "x = " << x << ", y = " << y << "\n";
    if(x == y) {
        //cout << "Answer = " << x << "\n";
        return x;
    }
    for(int i = 19; i >= 0; i--) {
        if(DP[i][x] != DP[i][y]) {
            x = DP[i][x];
            y = DP[i][y];
        }
    }
    //cout << "Answer = " << DP[0][x] << "\n";
    return DP[0][x];
}

void Update(int node) {
    ans[node] = 0;
    lastCnt[node] = cnt;
    int initial = node;
    while(centroidParent[node] != node) {
        node = centroidParent[node];
        //cout << "Update function, updating " << initial << "\n";
        //cout << "initial = " << initial << ", node = " << node << ", distance = " << distFromRoot[node] + distFromRoot[initial] - 2 * distFromRoot[LCA(initial, node)] << "\n";
        if(lastCnt[node] != cnt) {
            ans[node] = distFromRoot[node] + distFromRoot[initial] - 2 * distFromRoot[LCA(initial, node)];
            lastCnt[node] = cnt;
        }
        else {
            ans[node] = min(ans[node], distFromRoot[node] + distFromRoot[initial] - 2 * distFromRoot[LCA(initial, node)]);
        }
        //cout << "ans[node] = " << ans[node] << "\n";
    }
}

long long Query2(int node) {
    if(lastCnt[node] == cnt)
        return 0;
    int initial = node;
    long long res = 1e15;
    while(centroidParent[node] != node) {
        node = centroidParent[node];
        //cout << "Query function, querying " << initial << "\n";
        //cout << "LCA(initial, node) = " << LCA(initial, node) << "\n";
        //cout << "initial = " << initial << ", node = " << node << ", distance = " << distFromRoot[node] + distFromRoot[initial] - 2 * distFromRoot[LCA(initial, node)] << "\n";
        if(lastCnt[node] == cnt) {
            res = min(res, distFromRoot[node] + distFromRoot[initial] - 2 * distFromRoot[LCA(initial, node)] + ans[node]);
        }
        //cout << "res = " << res << "\n";
    }
    return res;
}

long long Query(int S, int X[], int T, int Y[]) {
    cnt++;
    for(int i = 0; i < S; i++) {
        Update(X[i]);
    }
    /*cout << "Outputting ans array\n";
    for(int i = 0; i < N; i++) {
        cout << ans[i] << " ";
    }
    cout << "\n";
    cout << "Outputting lastCnt array\n";
    for(int i = 0; i < N; i++) {
        cout << lastCnt[i] << " ";
    }
    cout << "\n";*/
    long long res = 1e15;
    for(int i = 0; i < T; i++) {
        res = min(res, Query2(Y[i]));
    }
    return res;
}

Compilation message

factories.cpp: In function 'void FindDist(int, int)':
factories.cpp:15:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   15 |     for(int i = 0; i < g[node].size(); i++) {
      |                    ~~^~~~~~~~~~~~~~~~
factories.cpp: In function 'int SubtreeDfs(int, int)':
factories.cpp:26:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   26 |     for(int i = 0; i < g[node].size(); i++) {
      |                    ~~^~~~~~~~~~~~~~~~
factories.cpp: In function 'int FindCentroid(int, int, int)':
factories.cpp:35:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   35 |     for(int i = 0; i < g[node].size(); i++) {
      |                    ~~^~~~~~~~~~~~~~~~
factories.cpp: In function 'void BuildCentroid(int, int)':
factories.cpp:53:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |     for(int i = 0; i < g[centroid].size(); i++) {
      |                    ~~^~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 35 ms 26988 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 20 ms 26604 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 35 ms 26988 KB Output isn't correct
2 Halted 0 ms 0 KB -