제출 #1346527

#제출 시각아이디문제언어결과실행 시간메모리
1346527nguyenkhangninh99Grapevine (NOI22_grapevine)C++20
0 / 100
139 ms47836 KiB

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

#define int long long
const int maxn = 1e5 + 5;
vector<array<int, 2>> adj[maxn];
int st[2 * maxn][19], lg2[2 * maxn], hanh[maxn], tin[maxn], h[maxn], timedfs;
int par[maxn], del[maxn], sz[maxn];

void build(int u, int p){
    tin[u] = ++timedfs;
    st[timedfs][0] = u;
    for(auto [v, w]: adj[u]){
        if(v == p) continue;
        hanh[v] = hanh[u] + w;
        h[v] = h[u] + 1;
        build(v, u);
        st[++timedfs][0] = u;
    }
}
int cmp(int u, int v){
    return (h[u] < h[v]) ? u : v;
}
int lca(int u, int v){
    int l = tin[u], r = tin[v];
    if(l > r) swap(l, r);
    int k = lg2[r - l + 1];
    return cmp(st[l][k], st[r - (1 << k) + 1][k]);
}

int dist(int u, int v){
    return hanh[u] + hanh[v] - 2 * hanh[lca(u, v)];
}

int dfs(int u, int p){
    sz[u] = 1;
    for(auto [v, w]: adj[u]){
        if (v != p && !del[v]) sz[u] += dfs(v, u);
    }
    return sz[u];
}

int centroid(int u, int p, int targ){
    for(auto [v, w]: adj[u]){
        if(v != p && !del[v] && sz[v] > targ / 2) return centroid(v, u, targ);
    }
    return u;
}

void decompose(int u, int p){
    u = centroid(u, -1, dfs(u, -1));
    del[u] = true; 
    par[u] = p;
    for(auto [v, w]: adj[u]) if(!del[v]) decompose(v, u);
}

int mnd[maxn]; 
void update(int u, int d){
    int cur = u;
    while(cur){
        mnd[cur] = min(mnd[cur], dist(u, cur) + d);
        cur = par[cur];
    }
}

int query(int u){
    int res = 1e15, cur = u;
    while(cur){
        res = min(res, dist(u, cur) + mnd[cur]);
        cur = par[cur];
    }
    return res;
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, q; cin >> n >> q;
    for(int i = 1; i <= n - 1; i++){
        int u, v, w; cin >> u >> v >> w;
        adj[u].push_back({v, w}); 
        adj[v].push_back({u, w});
    }

    build(1, 0);
    decompose(1, 0);
    for(int i = 2; i <= timedfs; i++) lg2[i] = lg2[i / 2] + 1;
    for(int j = 1; j <= 18; j++){
        for(int i = 1; i + (1 << j) - 1 <= timedfs; i++) st[i][j] = cmp(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
    }

    for(int i = 1; i <= n; i++) mnd[i] = 1e15;

    vector<int> at(n + 1);
    vector<array<int, 2>> qry;
    while(q--){
        int type; cin >> type;
        if(type == 1){
            int x; cin >> x;
            qry.push_back({x, -1});
        }
        if(type == 2){
            int x; cin >> x;
            at[x] = !at[x];
        }
        if(type == 3){
            int a, b, w; cin >> a >> b >> w;
            qry.push_back({a, b});
        }
    }
    for(int i = 1; i <= n; i++) if(at[i]) update(i, 0);
    for(auto [a, b]: qry){
        if(b == -1) cout << (query(a) >= 1e15 ? -1: query(a)) << '\n';
        else{
            int da = query(a), db = query(b);
            update(a, db);
            update(b, da);
        }
    }
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...