因為啟發式合併,所以我們強制用長鏈代表短鏈,遍歷修改短鏈的所有節點
由於我們只儲存了位置之間是同色的關係形成的鏈條,這些鏈條無顏色特徵,所以我們把長鏈分配給新顏色
即一次swap操作,用fa[x]記錄顏色x的在c陣列中儲存的真實顏色
其他部分就是水水細節啦。。
#include#include#include#include#include#include#includeusing namespace std;
#define ll long long
const int maxn=1e6+7;
const int inf=0x3f3f3f3f;
#define for(n) for(int i=1;i<=n;i++)
#define pb push_back
int n,m,ans;
int c[maxn],fa[maxn];
int size[maxn],head[maxn],nxt[maxn];
void merge(int x,int y)
for(int i=head[x];i;i=nxt[i])
} size[y]+=size[x];head[x]=size[x]=0;
}int main()
for(int op,x,y,i=1;i<=m;i++)
}}
HNOI2009 夢幻布丁 啟發式合併 佇列
傳送門 題意 n個布丁擺成一行,進行m次操作.每次將某個顏色的布丁全部變成另一種顏色的,然後再詢問當前一共有多少段顏色。題解 啟發式合併的神奇做法 把同種顏色的布丁排成一列,變色時接在那個顏色的佇列後面 同時要把短的佇列接在長的佇列後面。複雜度證明 由於每個操作中,合併短的佇列和長的佇列,合併後的佇...
HNOI2009 夢幻布丁(鍊錶 啟發式合併)
洛谷傳送門 開始乙個o n 2 思路,每次每句要改變顏色的點,改變完顏色後重新計算顏色的段數,顯然拉閘。然後呢。然後就不會了。看了別人部落格,才知道有個叫做啟發式合併的東西,就是把小的合併到大的上面,時間複雜度就將為了log級別,額,為啥呢?反正這樣就更快了。然後對於此題 我們先求出原序列的答案 每...
HNOI 2009 夢幻布丁 鍊錶 啟發式合併
題意 給出乙個序列,每個元素有顏色。共m次操作,改變一種顏色或統計顏色的塊數 由於m,n都比較大,所以我們直接mn暴力是不行的,要考慮優化。那麼mn慢在 呢?每次操作時,都要遍歷一遍整個序列,其中訪問到了很多沒用的元素。那麼就從這裡入手,如果我們每次只遍歷要修改的元素,就能快很多。所以我們用鍊錶,把...