• 阔力梯的树


    阔力梯的树

    题面

    点击查看

    题解

    树上问题, 树链剖分, lca变成线性, 点分治, 点分树, dsu on tree

    这道题是 dsu on tree, 还是要用时间戳这个好东西, 可以维护子树

    然后就是加子树入编号影响的问题, 用set维护就好了

    int n, m, _, k, cas;
    VI h[N];
    int dfn[N], low[N], df, son[N], sz[N], rk[N];
    ll ans[N], sum;
    set<int> st;
    
    void dfs(int x) {
        rk[dfn[x] = ++df] = x, sz[x] = 1;
        for (auto &y : h[x]) {
            dfs(y); sz[x] += sz[y];
            if (!son[x] || sz[y] > sz[son[x]]) son[x] = y;
        }
        low[x] = df;
    }
    
    void add(ll x) {
        if (st.empty()) { st.insert(x); return; }
        auto it = st.lower_bound(x);
        if (it == st.begin()) sum += sqr(x - *it), st.insert(x);
        else if (it == st.end()) --it, sum += sqr(x - *it), st.insert(x);
        else {
            ll cur = *it; sum += sqr(x - cur); --it;
            sum += sqr(x - *it) - sqr(*it - cur); st.insert(x); 
        }
    }
    
    void dsu(int x, bool f) {
        for (auto &y : h[x]) if (y ^ son[x]) dsu(y, 0);
        if (son[x]) dsu(son[x], 1);
        for (auto &y : h[x]) if (y ^ son[x]) rep (j, dfn[y], low[y]) add(rk[j]);
        add(x); ans[x] = sum;
        if (!f) clear(st), sum = 0;
    }
    
    int main() {
        IOS; cin >> n;
        rep (i, 2, n) cin >> m, h[m].pb(i);
        dfs(1); dsu(1, 0);
        rep (i, 1, n) cout << ans[i] << '
    ';
        return 0;
    }
    
  • 相关阅读:
    同步gitlab与github
    配置hosts快速访问GitHub
    Linux下Julia安装
    LATEX图片位置
    IPOPT安装
    sqlplus传入shell变量
    users表空间满导致应用无法连接
    坏块修复 ORA-00701
    Oracle中INITRANS和MAXTRANS参数(转)
    DBMS_ROWID包的使用
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14539472.html
Copyright © 2020-2023  润新知