zoukankan      html  css  js  c++  java
  • 阔力梯的树

    阔力梯的树

    题面

    点击查看

    题解

    树上问题, 树链剖分, 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;
    }
    
  • 相关阅读:
    数组模拟队列
    数组模拟栈
    数组实现双链表
    别再傻傻地说电脑内存不够用了,望周知!
    电脑内存又不够了?六个方法拯救你的C盘!
    jsp基础语法与指令
    最新的web.xml配置代码
    浅谈Session技术
    浅谈cookie技术
    Javaweb编程之Response下载文件
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14539472.html
Copyright © 2011-2022 走看看