1 条题解

  • 0
    @ 2025-10-19 16:38:57

    题解

    (请在此补充题目的中文题解与思路描述。)

    #include <bits/stdc++.h>
    using namespace std;
    #define FILE(x) freopen(x".in", "r", stdin); freopen(x".out", "w", stdout)
    #define ll long long
    #define ld long double
    #define il inline
    #define pii pair <int, int>
    #define pil pair <int, ll>
    #define pli pair <ll, int>
    #define fi first
    #define se second
    #define mid (l + r >> 1)
    #define ls (p << 1)
    #define rs (p << 1 | 1)
    #define pb push_back
    #define popc __builtin_popcount
    #define inf 1000000000
    #define pinf {(ll)(8e18), 0}
    const int N = 1e5 + 5;
    int n, m, cur = 1, dfn, L[N], R[N], de[N], fa[N][18]; ll _, a[N], b[N], t[N];
    vector <pil> g[N];
    void dfs(int u, int f)
    {
        fa[u][0] = f; de[u] = de[f] + 1; L[u] = ++dfn;
        for (int h = 1; h <= 17; h++) fa[u][h] = fa[fa[u][h-1]][h-1];
        for (auto [v, w] : g[u]) if (v != f) b[v] = w, dfs(v, u);
        R[u] = dfn;
    }
    int lca(int u, int v)
    {
        if (de[u] < de[v]) swap(u, v); int dc = de[u] - de[v];
        for (int i = 17; i >= 0; i--) if (dc >> i & 1) u = fa[u][i];
        if (u == v) return u;
        for (int i = 17; i >= 0; i--) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    void mdf(int l, int r, ll v)
    {
        for (; l <= n; l += l & -l) t[l] += v;
        for (r++; r <= n; r += r & -r) t[r] -= v;
    }
    ll qry(int x) {ll s = 0; for (; x; x -= x & -x) s += t[x]; return s;}
    ll dis(int u, int v) {return qry(L[u]) + qry(L[v]) - 2 * qry(L[lca(u,v)]);}
    int q[N], h, fa2[N], sz[N], mx[N]; bool o[N]; vector <int> anc[N], sub[N];
    int fnd(int rt)
    {
        q[h=1] = rt;
        for (int i = 1; i <= h; i++)
        {
            int u = q[i]; sz[u] = 1; mx[u] = 0;
            for (auto [v, w] : g[u]) if (o[v] && v != fa2[u]) q[++h] = v, fa2[v] = u;
        }
        for (int i = h; i > 1; i--) 
        {
            int v = q[i], u = fa2[v];
            sz[u] += sz[v]; mx[u] = max(mx[u], sz[v]);
        }
        int ret = 0, mn = inf;
        for (int i = 1; i <= h; i++)
        {
            int u = q[i]; 
            if (sz[rt] - sz[u] > mx[u]) mx[u] = sz[rt] - sz[u];
            if (mx[u] < mn) mn = mx[u], ret = u;
        }
        return ret;
    }
    void dfz(int u, int f)
    {
        int rt = fnd(u);
        q[h=1] = rt; fa2[rt] = o[rt] = 0;
        for (int i = 1; i <= h; i++)
        {
            int u = q[i];
            for (auto [v, w] : g[u]) if (o[v] && v != fa2[u]) q[++h] = v, fa2[v] = u;
        }
        for (int i = 1; i <= h; i++) anc[q[i]].pb(rt), sub[rt].pb(L[q[i]]);
        for (auto [v, w] : g[rt]) if (o[v]) dfz(v, rt);
    }
    int pos(vector <int>& o, int x) {return lower_bound(o.begin(), o.end(), x) - o.begin() + 1;}
    struct sgt
    {
        int n; vector <ll> tg; vector <pli> t1, t2;
        void crt(int _n) {n = _n; tg.resize(4 * n + 5); t1.resize(4 * n + 5); t2.resize(4 * n + 5);}
        void pu(int p)
        {
            if (t1[ls] < t1[rs]) t1[p] = t1[ls], t2[p] = min(t2[ls], t1[rs]);
            else t1[p] = t1[rs], t2[p] = min(t1[ls], t2[rs]);
        }
        void pt(int p, ll v) {tg[p] += v; t1[p].fi += v; t2[p].fi += v;}
        void pd(int p) {if (tg[p]) pt(ls, tg[p]), pt(rs, tg[p]), tg[p] = 0;}
        void mdf(int p, int l, int r, int a, pli v)
        {
            if (l == r) return t1[p] = v, t2[p] = pinf, void(); pd(p);
            if (a <= mid) mdf(ls, l, mid, a, v); else mdf(rs, mid + 1, r, a, v); pu(p);
        }
        void mdf(int p, int l, int r, int a, int b, ll v)
        {
            if (a > b) return; if (a <= l && r <= b) return pt(p, v); pd(p);
            if (a <= mid) mdf(ls, l, mid, a, b, v); if (b > mid) mdf(rs, mid + 1, r, a, b, v); pu(p);
        }
    } T[N];
    int main()
    {
        // FILE("");
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1, u, v; i < n; i++) cin >> u >> v >> _, g[u].pb({v, _}), g[v].pb({u, _});
        dfs(1, 0); memset(o, 1, sizeof(o)); dfz(1, 0);
        for (int u = 1; u <= n; u++) mdf(L[u], R[u], b[u]), sort(sub[u].begin(), sub[u].end()), T[u].crt(sub[u].size());
        for (int u = 1; u <= n; u++) for (int v : anc[u]) T[v].mdf(1, 1, T[v].n, pos(sub[v], L[u]), {dis(u, v) - a[u], u});
        while (m--)
        {
            int op, x, y; ll w; pli ans = pinf;
            cin >> op;
            if (op == 1)
            {
                cin >> x >> w; a[x] = w;
                for (int u : anc[x]) T[u].mdf(1, 1, T[u].n, pos(sub[u], L[x]), {dis(u, x) - a[x], x});
            }
            else 
            {
                cin >> x >> y >> w; if (de[x] > de[y]) swap(x, y); 
                int z = (anc[x].size() >= anc[y].size() ? x : y); 
                for (int u : anc[z])
                {
                    if (L[y] <= L[u] && L[u] <= R[y]) 
                        T[u].mdf(1, 1, T[u].n, 1, pos(sub[u], L[y] + 1) - 1, w - b[y]), 
                        T[u].mdf(1, 1, T[u].n, pos(sub[u], R[y]), T[u].n, w - b[y]);
                    else T[u].mdf(1, 1, T[u].n, pos(sub[u], L[y]), pos(sub[u], R[y] + 1) - 1, w - b[y]);
                }
    			mdf(L[y], R[y], w - b[y]); b[y] = w;
    		}
            for (int u : anc[cur]) 
            {
                pli ret = T[u].t1[1].se != cur ? T[u].t1[1] : T[u].t2[1];
                ret.fi += dis(cur, u); ans = min(ans, ret);
            }
            cout << (cur = ans.se) << " \n"[!T];
        }
        return 0;
    }
    
    • 1

    信息

    ID
    3394
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    4
    已通过
    1
    上传者