修改陣列 平衡樹 維護區間 經典題

2021-10-03 17:44:44 字數 1821 閱讀 3421

給定乙個長度為 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。

資料範圍

1≤n≤105,

1≤ai≤106

輸入樣例:

52 1 1 3 4

輸出樣例:

2 1 3 4 5

#include

#include

#include

#include

#include

#include

using

namespace std;

int n;

typedef pair<

int,

int> pii;

set sgs;

intmain()

);printf

("%d "

, x)

;continue;}

//在集合中去找乙個區間包含x的,本來我們只需要找乙個數x,但是由於set裡面存的區間,乙個數和乙個區間肯定無法直接比較大小,所以我們要把這個數x變成乙個區間,即,就可以用lower_bound查詢了,找到的是第乙個大於或等於這個pair的pair(pair先比較第乙個關鍵字的大小。如果相等,再比較第二個關鍵字的大小)。

//二分查詢包含x的區間

auto it = sgs.

lower_bound

(pii

(x, int_min));

//如果包含 即[*,?] (?>=x)

if(it != sgs.

end(

)&& it-

>second <= x));

auto back = sgs.

lower_bound

(pii

(x+1

, int_min));

if(back != sgs.

end(

)&& back-

>second == x +1)

}else);

}}//定位[?,x]

it = sgs.

lower_bound

(pii

(x, int_min));

auto back = sgs.

lower_bound()

;if(back != sgs.

end(

)&& back-

>second == it-

>first +1)

}printf

("%d "

, x);}

printf

("\n");

return0;

}

樹狀陣列維護區間和和區間修改

可以用樹狀陣列在 n logn 內,雖然線段樹也能,但是樹狀陣列的 空間都要比它優越得多.首先我們可以用差分的方法使區間修改可以在log的複雜度完成,但重點在於區間和的查詢.我們知道,此時num i a 1 a 2 a i 可以利用樹狀陣列快速求出.而區間和則是 a 1 a 2 a i a 1 a ...

疑難雜題筆記 修改陣列

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

區間MEX 線段樹維護mex陣列

問題描述 給你乙個長度為n的數列,元素編號1到n,第i個元素值為ai。現在有m個形如 l,r 的提問,你需要回答出區間 l,r 的mex值。即求出區間 l,r 中沒有出現過的最小的非負整數。輸入格式 第一行,兩個整數n和m 第二行,n個空格間隔的整數,表示數列a 接下來m行,每行兩個整數l,r,表示...