藍橋杯 修改陣列 並查集

2021-09-19 13:51:20 字數 1486 閱讀 1352

修改陣列

時間限制: 1.0s 記憶體限制: 256.0mb 本題總分:20 分

【問題描述】

給定乙個長度為 n 的陣列 a = [a1, a2, · · · an],陣列中有可能有重複出現的整數。

現在小明要按以下方法將其修改為沒有重複整數的陣列。小明會依次修改

a2, a3, · · · , an。

當修改 ai 時,小明會檢查 ai 是否在 a1 ~ ai-1 **現過。如果出現過,則小明會給 ai 加上 1 ;如果新的 ai 仍在之前出現過,小明會持續給 ai 加 1 ,直到 ai 沒有在 a1 ~ ai-1 **現過。

當 an 也經過上述修改之後,顯然 a 陣列中就沒有重複的整數了。現在給定初始的 a 陣列,請你計算出最終的 a 陣列。

【輸入格式】

第一行包含乙個整數 n。

第二行包含 n 個整數 a1, a2, · · · , an 。

【輸出格式】

輸出 n 個整數,依次是最終的 a1, a2, · · · , an。

【樣例輸入】

52 1 1 3 4

【樣例輸出】

2 1 3 4 5

【評測用例規模與約定】

對於 80% 的評測用例,1 ≤ n ≤ 10000。

對於所有評測用例,1 ≤ n ≤ 100000,1 ≤ ai ≤ 1000000。

解題思路

bool標記每次+1很容易就t了(如果有n個數,全都為n,那麼這是o(n^2/2)的複雜度,當n=1e5時就已經超時了)。這題可以巧妙地利用並查集。 我們初始化i的父親為i,然後依次遍歷輸入的陣列,使a[i] = getf(a[i]),再令f(a[i]) = f(a[i]+1)即可。

假如我們連續輸入1,2,1,第一次輸入1,a[1] = getf(1) = 1,更新f[1] = getf(a[1]+1) = 2; 第二次輸入  輸入2,a[2] = getf(2) =2,更新f[2] = getf(a[2]+1) = 3,第三次 再輸入1,a[3] = getf(1) = getf(2) = 3, 這時候a[3]便等於3了,而這種的時間複雜度僅為o( logn)。  很巧妙 好好體會。

整體時間複雜度o(n*logn*logn)。 

code

#include using namespace std;

const int maxn = 1e6+5;

int a[maxn],f[maxn];

int getf(int x)

int main()

for(int i=1;i<=n;i++)

return 0;

}

藍橋杯省賽 修改陣列(並查集)

給定乙個長度為n 的陣列a a1,a2,an 陣列中有可能有重複出現的整數。現在小明要按以下方法將其修改為沒有重複整數的陣列。小明會依次修改a2,a3,an。當修改ai 時,小明會檢查ai 是否在a1 ai 1 現過。如果出現過,則小明會給ai 加上1 如果新的ai 仍在之前出現過,小明會持續給ai...

藍橋杯 並查集

c國由n個小島組成,為了方便小島之間聯絡,c國在小島間建立了m座大橋,每座大橋連線兩座小島。兩個小島間可能存在多座橋連線。然而,由於海水沖刷,有一些大橋面臨著不能使用的危險。如果兩個小島間的所有大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能通過其他的橋或者其他的小島互相到...

藍橋杯 國王的煩惱(並查集)

include include include includeusing namespace std const int maxn 1e5 5 int n,m,pre maxn struct node a maxn int find int x return r bool join int x,in...