啟發式合併

2022-05-12 10:41:00 字數 1917 閱讀 4620

啟發式演算法是什麼?

啟發式演算法是基於人類的經驗和直觀感覺,對一些演算法的優化。

比如說啟發式搜尋\(a\)*演算法。

啟發式合併是什麼?

考慮乙個問題:把\(n\)個總元素個數為\(m\)的資料結構合併起來(假設是線性的)。

每次合併複雜度最壞\(o(m)\),總複雜度\(o(nm)\)?顯然無法接受。

每次把個數少的合併到個數多的?複雜度\(o(min(m_1, m_2))\)

好像沒啥用?

可是我們注意到,每次合併後個數為合併前少的部分的個數的兩倍以上,每個元素最多合併\(logm​\)次,總複雜度\(o(mlogm)​\)。

我們也可以啟發式合併更加高階的資料結構,如\(heap\),\(set\),\(splay\)等,複雜度\(o(mlog^2m)\)

很玄學?但這個複雜度分析是對的,而且跑的也快。

例題:hnoi2009 夢幻布丁

題意就不贅述了。

對於每乙個顏色,建一條鍊錶。然後染色就是把鏈短的合併到鏈長的。

需要注意細節,如果把\(2\)染成\(3\),但\(2\)的鏈比\(3\)的長,就需要把\(3\)的合併到\(2\)上。但是現在本應屬於\(3\)的鏈在\(2\)上,就需要記乙個該顏色的鏈現在在哪個顏色上,即是**中的\(now\)陣列。

#include#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)

#define per(i, a, b) for (register int i=(a); i>=(b); --i)

using namespace std;

void swap(int &x, int &y)

const int n=1000005;

int head[n], nxt[n], col[n], now[n], cnt[n], st[n], ans;

inline int read()

void merge(int x, int y)

for (int i=head[x]; i; i=nxt[i]) col[i]=y;

nxt[st[x]]=head[y]; head[y]=head[x];

head[x]=st[x]=cnt[x]=0;

}int main()

rep(i, 1, m)

}return 0;

}

在看一道新鮮出爐的聯考題:春節十二響

題意比較複雜,自己看吧$qaq $。

考慮鏈的部分分做法,將兩條支鏈分別排序,然後從大到小加上兩邊的\(max\)即可。

那麼我們就有了乙個暴力做法。對每個點維護乙個堆,每次像鏈那樣暴力合併即可,複雜度大概是\(o(n^2logn)\)?

改成啟發式合併就可以了,每次把小的堆合併到大的堆上。時間複雜度\(o(nlog^2n)\),其實跑的很快。

#include#include#include#define rep(i, a, b) for (register int i=(a); i<=(b); ++i)

#define per(i, a, b) for (register int i=(a); i>=(b); --i)

using namespace std;

const int n=200005;

vectorg[n], q;

priority_queueq[n];

int val[n], id[n], n; long long ans;

inline int read()

void dfs(int u)

{ for (int v: g[u])

{dfs(v);

if (q[id[u]].size()本來這裡還有乙個題,經提醒並不是啟發式合併,故刪去

啟發式合併

啟發式合併 暴力合併 將兩個資料結構合併,只需要將小的資料結構中的元素乙個乙個的插入大的資料結構o n o n o n 如果題目只有插入操作沒有 總o n logn o nlogn o nlog n 因為每次合併,所有資料結構總大小為n,設兩個資料結構大小為a,b a b a,b a b a,b a...

啟發式合併

includeconst int n 5e5 5 int f n d n r n p n int find int i int unionn int i,int j int main 並查集 按秩啟發式合併 bzoj4668 冷戰 題目大意 給出n個軍工廠和m 個操作,操作分為兩類 0 u v,這次...

啟發式合併

啟發式合併本質上是一種優化的暴力,可用於擁有穩定結構的資料結構。考慮夢幻布丁 hnoi2009 顯然的暴力思路是用鍊錶維護每種顏色的位置,然後每次修改的時候暴力合併兩條鏈。不難證明,這樣的最壞時間複雜度將達到 o n 2 不能接受。可以觀察到,合併的時間複雜度只與被合併的鏈長度有關,所以可以想到優化...