CF600E Lomsat gelral(DSU on tree)

題面
先考慮O(n2)O(n^2)暴力,DFSDFS到每個點之後再暴力統計它的子樹答案即可
仔細觀察,我們發現一個點沒有好好利用它兒子的貢獻.可以發現,每個點最後遍歷到的一棵子樹貢獻可以被保留,這樣計算該節點答案的時候就可以少遍歷最後一棵子樹,直接利用最後一棵子樹的貢獻.顯然把最大的子樹留到最後遍歷最優,可以證明這樣做是O(nlogn)O(nlogn)的(然而我並不會證)

void dfs(LL now,LL fa,LL keep=0){//keep=1則保留貢獻
    out(i,v,now)
    if (to!=fa && to!=son[now]){
        dfs(to,now);//遍歷其它子樹
    }
    if (son[now]) dfs(son[now],now,1);//遍歷最大的子樹
    inc(col[now]);
    out(i,v,now) if (to!=fa && to!=son[now]) xg(to,now,1);//統計答案
    ans[now]=cnt[ma];
    if (!keep){
        dec(col[now]);
        out(i,v,now) if (to!=fa) xg(to,now,-1);
    }
}

Code

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章