답안 #957956

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
957956 2024-04-04T14:15:39 Z steveonalex 공장들 (JOI14_factories) C++17
0 / 100
32 ms 58252 KB
#include "factories.h"

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define MASK(i) (1LL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()

ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}

ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ll mask){return __builtin_popcountll(mask);}
int ctz(ll mask){return __builtin_ctzll(mask);}
int logOf(ll mask){return 63 - __builtin_clzll(mask);}

mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
// mt19937_64 rng(69);
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}

template <class T1, class T2>
    bool maximize(T1 &a, T2 b){
        if (a < b) {a = b; return true;}
        return false;
    }

template <class T1, class T2>
    bool minimize(T1 &a, T2 b){
        if (a > b) {a = b; return true;}
        return false;
    }

template <class T>
    void printArr(T& container, string separator = " ", string finish = "\n", ostream &out = cout){
        for(auto item: container) out << item << separator;
        out << finish;
    }

template <class T>
    void remove_dup(vector<T> &a){
        sort(ALL(a));
        a.resize(unique(ALL(a)) - a.begin());
    }

const int N = 5e5 + 69, LOG_N = 19;
const ll INF = 1e18 + 69;
int n;
vector<pair<int, int>> graph[N];
pair<int, int> rmq[LOG_N + 1][N * 2];
int l[N], pos[N * 2], h[N];
ll sum[N];
int dfs_cnt;
ll ans;


vector<pair<int, ll>> virtual_tree[N];
int mode[N];
ll cur_sum[N];
ll dp[N][2];

void reset(){
    dfs_cnt = 0;
    ans = INF;
    for(int i = 0; i<n; ++i){
        graph[i].clear(); virtual_tree[i].clear();
        mode[i] = -1;
        cur_sum[i]= 0;
        h[i] = sum[i] = 0;
        dp[i][0] = dp[i][1] = INF;
    }
}

void init_lca(int u, int p){
    l[u] = ++dfs_cnt;
    pos[dfs_cnt] = u;
    rmq[0][dfs_cnt] = {h[u], u};
    for(auto v: graph[u]) if (v.first != p){
        h[v.first] = h[u] + 1;
        sum[v.first] = sum[u] + v.second;
        init_lca(v.first, u);
        rmq[0][++dfs_cnt] = {h[u], u};
    }
}

void init_rmq(){
    for(int j = 1; MASK(j) <= n * 2 - 1; ++j)
    for(int i= 1; i + MASK(j) - 1 <= n * 2 - 1; ++i) rmq[j][i] = min(rmq[j-1][i], rmq[j-1][i + MASK(j-1)]);
}

int LCA(int u, int v){
    u = l[u], v = l[v];
    if (u > v) swap(u, v);
    int j = logOf(v - u + 1);
    return min(rmq[j][u], rmq[j][v - MASK(j) + 1]).second;
}

ll sum_path(int u, int v){
    int lck = LCA(u, v);
    return sum[u] + sum[v] - 2 * sum[lck];
}

void Init(int _n, int A[], int B[], int D[]) {
    n = _n;
    reset();
    for(int i= 0; i<n-1; ++i){
        int u = A[i], v = B[i], w = D[i];
        graph[u].push_back({v, w});
        graph[v].push_back({u, w});
    }
    init_lca(0, 0);
    init_rmq();
}



void go(int u){
    if (mode[u] != -1) minimize(dp[u][mode[u]], cur_sum[u]);
    for(auto v: virtual_tree[u]){
        cur_sum[v.first] = cur_sum[u] + v.second;
        go(v.first);
        for(int x = 0; x <= 1; ++x)
            minimize(ans, dp[u][x] + dp[v.first][!x] - cur_sum[u] * 2);
        for(int x = 0; x <= 1; ++x) minimize(dp[u][x], dp[v.first][x]);
    }
}

ll Query(int S, int X[], int T, int Y[]) {
    vector<int> x, y;
    for(int i = 0; i<S; ++i) x.push_back(l[X[i]]);
    for(int i = 0; i<T; ++i) y.push_back(l[Y[i]]);

    remove_dup(x); remove_dup(y);

    for(int i: x) if (binary_search(ALL(y), i)) return 0;

    vector<int> ver(x.size() + y.size());
    merge(ALL(x), ALL(y), ver.begin());

    for(int i = ver.size() - 1; i>=1; --i) {
        int u = pos[ver[i]], v = pos[ver[i-1]];
        ver.push_back(l[LCA(u, v)]);
    }

    remove_dup(ver);

    for(int &i: ver) i = pos[i];

    reverse(ALL(ver));
    vector<int> st;
    for(int i: ver){
        while(st.size()){
            if (LCA(st.back(), i) == i){
                int u = st.back(), v = i;
                st.pop_back();
                virtual_tree[v].push_back({u, sum[u] - sum[v]});
            }
            else break;
        }
        st.push_back(i);
    }

    int root= st.back();
    ans = INF;

    for(int i: x) mode[pos[i]] = 0;
    for(int i: y) mode[pos[i]] = 1;
    cur_sum[root] = 0;
    go(root);

    for(int i: ver) {
        virtual_tree[i].clear();
        mode[i] = -1;
    }

    return ans;
}


// int main(void){
//     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//     int n, q; cin >> n >> q;
//     int A[n-1], B[n-1], D[n-1];
//     for(int i= 0; i<n-1; ++i) cin >> A[i] >> B[i] >> D[i];

//     Init(n, A, B, D);

//     while(q--){
//         int s, t; cin >> s >> t;
//         int u[s], v[t];
//         for(int i= 0; i<s; ++i) cin >> u[i];
//         for(int i= 0; i<t; ++i) cin >> v[i];

//         cout << Query(s, u, t, v) << "\n";
//     }

//     return 0;
// }
# 결과 실행 시간 메모리 Grader output
1 Incorrect 32 ms 58252 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 12 ms 55900 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 32 ms 58252 KB Output isn't correct
2 Halted 0 ms 0 KB -