time limit: 10 sec
memory limit: 64 mb
submit: 2341
solved: 965 [
submit][
status][
discuss]
n個布丁擺成一行,進行m次操作.每次將某個顏色的布丁全部變成另一種顏色的,然後再詢問當前一共有多少段顏色.例如顏色分別為1,2,2,1的四個布丁一共有3段顏色.
第一行給出n,m表示布丁的個數和好友的操作次數. 第二行n個數a1,a2...an表示第i個布丁的顏色從第三行起有m行,對於每個操作,若第乙個數字是1表示要對顏色進行改變,其後的兩個整數x,y表示將所有顏色為x的變為y,x可能等於y. 若第乙個數字為2表示要進行詢問當前有多少段顏色,這時你應該輸出乙個整數. 0
針對第二類操作即詢問,依次輸出當前有多少段顏色.
4 31 2 2 1
21 2 123
1
解題思路:完全沒有想到可以啟發式合併。以後遇到
合併的題可以考慮。這道題就是用啟發式合併鏈,
由於是少的插到多的,所以還要記錄每個顏色查詢時
真正所對的顏色。
#include
#include
#include
using namespace std;
int n,m,ans;
int c[300000],fa[1000100],next[300000],head[1000100],sz[1000100];
inline int read()
while (y>='0' && y<='9')
return x*f;
} void merge(int u,int v)
head[v]=head[u]; head[u]=0; sz[v]+=sz[u]; sz[u]=0;
}int main()
for (int i=1;i<=m;++i)
else }
}
啟發式合併
啟發式合併 暴力合併 將兩個資料結構合併,只需要將小的資料結構中的元素乙個乙個的插入大的資料結構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 不能接受。可以觀察到,合併的時間複雜度只與被合併的鏈長度有關,所以可以想到優化...