"SDOI2015" treasure hunt

Portal
Luogu

Problem-solving ideas

Found a property:
for all the treasures points \ ({A_1, A_2 a_k ...} \) , dfs according to ascending order, the answer is:
\ (DIS (A_1, A_2) + DIS (A_2, A_3) + \ cdots + dis (a_ {k-1
}, a_k) + dis (a_k, a_1) \) consider adding a point contribution:
Suppose the added point \ (U \) , then the contribution of that \ (dis (L, u) + dis (R, u) -
dis (L, R) \) where \ (L, R \) are \ (U \) points corresponding to the predecessor and successor sequence dfs.
This should be good to understand.
Then we engage in a set can be maintained.

Details Notes

  • Gugu Gu

Reference Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <set>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

typedef long long LL;
const int _ = 100010;

int tot, head[_], nxt[_ << 1], ver[_ << 1], w[_ << 1];
inline void Add_edge(int u, int v, int d)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; }

int n, m, num, vis[_]; LL dis[_];
int fa[_], siz[_], dep[_], top[_], son[_], dfn[_], id[_];
set < int > s;
set < int > ::iterator it;

inline void dfs1(int u, int f) {
    fa[u] = f, dep[u] = dep[f] + 1;
    siz[u] = 1, id[dfn[u] = ++num] = u;
    for (rg int v, i = head[u]; i; i = nxt[i])
        if (!dep[v = ver[i]]) {
            dis[v] = dis[u] + w[i];
            dfs1(v, u), siz[u] += siz[v];
            if (siz[son[u]] < siz[v]) son[u] = v;
        }
}

inline void dfs2(int u, int topf) {
    top[u] = topf;
    if (!son[u]) return; dfs2(son[u], topf);
    for (rg int v, i = head[u]; i; i = nxt[i])
        if (!top[v = ver[i]]) dfs2(v, v);
}

inline int LCA(int x, int y) {
    int fx = top[x], fy = top[y];
    while (fx != fy) {
        if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
        x = fa[fx], fx = top[x];
    }
    return dep[x] < dep[y] ? x : y;
}

inline LL dist(int x, int y) { return dis[x] + dis[y] - 2 * dis[LCA(x, y)]; }

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    read(n), read(m);
    for (rg int u, v, d, i = 1; i < n; ++i)
        read(u), read(v), read(d), Add_edge(u ,v, d), Add_edge(v, u, d);
    dfs1(1, 0), dfs2(1, 1);
    LL ans = 0;
    while (m--) {
        int x, d; read(x), d = dfn[x];
        if (!vis[x]) s.insert(d);
        int l = id[(it = s.lower_bound(d)) == s.begin() ? *--s.end() : *--it];
        int r = id[(it = s.upper_bound(d)) == s.end() ? *s.begin() : *it];
        if (vis[x]) s.erase(d);
        LL delta = dist(l, x) + dist(r, x) - dist(l, r);
        if (vis[x]) ans -= delta, vis[x] = 0;
        else ans += delta, vis[x] = 1;
        printf("%lld\n",  ans);
    }
    return 0;
}

End Sahua \ (qwq \)

Guess you like

Origin www.cnblogs.com/zsbzsb/p/11746534.html