社区讨论

10pts only AC on #4 求调

P3320[SDOI2015] 寻宝游戏参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mlh9k78i
此快照首次捕获于
2026/02/11 08:00
上周
此快照最后确认于
2026/02/12 16:40
7 天前
查看原帖
直接把异象石搬过来改了改,自己又调了一遍感觉没问题啊/ll
CPP
#include <iostream>
#include <set>
#include <algorithm>
#define int long long

using namespace std;

constexpr int N = 1e5 + 5;
int n, q;

int head[N], nxt[N << 1], ver[N << 1], spd[N << 1], tot;
inline void add (int a, int b, int c) {
    ver[++ tot] = b, spd[tot] = c;
    nxt[tot] = head[a], head[a] = tot;
}

int dis[N], dep[N];
int dfn[N], bac[N], idx;
int jmp[N][25];
void dfs (int x, int fa) {
    jmp[x][0] = fa, dep[x] = dep[fa] + 1;
    for (int i = 1; i <= 20; ++ i) {
        jmp[x][i] = jmp[jmp[x][i - 1]][i - 1];
    }
    dfn[x] = ++ idx, bac[idx] = x;
    for (int i = head[x]; i; i = nxt[i]) {
        int y = ver[i];
        if (y == fa) continue;
        dis[y] = dis[x] + spd[i];
        dfs(y, x);
    }
}
inline int LCA (int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = 20; i >= 0; -- i) {
        if (dep[jmp[x][i]] >= dep[y]) x = jmp[x][i];
    }
    if (x == y) return x;
    for (int i = 20; i >= 0; -- i) {
        if (jmp[x][i] != jmp[y][i]) {
            x = jmp[x][i], y = jmp[y][i];
        }
    }
    return jmp[x][0];
}
inline int getdis (int x, int y) {
    return dis[x] + dis[y] - (dis[LCA(x, y)] << 1);
}

int sum;
set <int> st;

inline void add_node (int x) {
    set <int> :: iterator it = st.insert(dfn[x]).first;
    if (st.size() > 2) {
        set <int> :: iterator pre = it, nxt = it;
        if (pre == st.begin()) pre = -- st.end();
        else -- pre;
        if (++ nxt == st.end()) nxt = st.begin();
        
        int l = bac[*pre], r = bac[*nxt];
        sum += getdis(l, x) + getdis(x, r) - getdis(l, r);
    } else if (st.size() == 2) {
        set <int> :: iterator tmp = it;
        if (tmp == st.begin()) ++ tmp;
        else tmp = st.begin();
        sum = getdis(bac[*tmp], x) << 1;
    }
}

inline void del_node (int x) {
    set <int> :: iterator it = st.find(dfn[x]);
    if (st.size() > 2) {
        set <int> :: iterator pre = it, nxt = it;
        if (pre == st.begin()) pre = -- st.end();
        else -- pre;
        if (++ nxt == st.end()) nxt = st.begin();
        
        int l = bac[*pre], r = bac[*nxt];
        sum -= getdis(l, x) + getdis(x, r) - getdis(l, r);
    } else if (st.size() == 2) {
        sum = 0;
    }
    st.erase(dfn[x]);
}

signed main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> q;
    for (int i = 1; i < n; ++ i) {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    dfs(1, 0);
    int x;
    while (q --) {
    	cin >> x;
    	add_node(x);
    	cout << sum << '\n';
    }
    return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...