樹上啟發式合併qwq,一聽就是很高階的演算法,其實也不難。
這個演算法主要也只能應用於:
子樹統計
無修改操作
首先進行輕重鏈剖分,和樹剖不同的是,我們每次先dfs輕兒子,暴力統計答案大小,並且暴力刪除輕兒子產生的影響。最後dfs重兒子,就是為了保留下重兒子的影響。
那時間複雜度為什麼是對的呢?
只有dfs到輕邊時,才會將輕邊的子樹中合併到上一級的重鏈,樹鏈剖分將一棵樹分割成了不超過logn條重鏈。
每乙個節點最多向上合併logn次,單次修改複雜度o(1)。
所以整體複雜度是o(nlogn)的。
那麼cf600e就是這樣一道題目啊!
#include
#define maxn 100005
#define ll long long
using namespace std;
struct node*con[maxn];
void addedge(int x,int y)
int c[maxn],n,sz[maxn],a[maxn],maxv,hs[maxn];
ll sum,ans[maxn];
bool vis[maxn];
void calc(int v,int fa,int k)//計算貢獻
for(node*p=con[v];p;p=p->next)
if(p->to!=fa&&!vis[p->to]) calc(p->to,v,k);
}void dfs1(int v,int fa)//輕重鏈剖分
}void dfs2(int v,int fa,bool tmp)
int main()
{ scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i
樹上啟發式合併
解決樹上統計問題,o n log n o n log n o n lo g n 可以結合線段樹等資料結構維護深度上的資訊 部落格 入門題 const int maxn 1e5 7 const int mod 1e9 7 ll n,m,u,v,mx,sum vector int mp maxn int...
樹上啟發式合併
樹上啟發式合併,一種美妙的黑科技,可以用普通的優化讓你 n 2 變成嚴格 n log 解決一些類似 樹上數顏色,樹上查眾數 這樣的問題 首先你要知道暴力為什麼是 n 2 的 以這個圖為例 每次你從乙個節點開始向下搜,你從1節點搜到3,搜完這個子樹然後你需要把3存的col等資訊刪去再遍歷另乙個子樹才是...
樹上啟發式合併總結
某一天發現一道樹上啟發式合併裸題,但我不會寫 學習並刷了兩天的題,是時候來寫個總結了 樹上啟發式合併 dsu on tree 是乙個在o n logn o nlogn o nlog n 時間內解決許多樹上問題的有力演算法。但它的中心其實是 暴力!沒錯,它正是由暴力優化而來。我們先看一道例題 cf60...