2019 CCPC 網路選拔 array

2022-04-30 07:48:14 字數 1571 閱讀 1730

給乙個\(1\)到\(n\)的排列

現在有\(m\)個操作,每個操作是下面的一種:

\(t\leq 10,1\leq n \leq 10^5, 1\leq m \leq 10^5 ,1\leq k\leq n\)

考場上頭鐵,硬肝了\(4h\)

結考後\(20\)分鐘調出來,\(1a...\)但想出來還是很高興的

我們會發現每次給出的\(k\)都在\([1,n]\)範圍內,那麼我們操作二中輸出的數最大也就是\(n+1\)

所以給\(pos\)位上的數加上\(10^7\)實際上相當於把這個數從排列中刪除

我們主要看第二個操作

對於\(2,3\)兩個條件,我們能夠很快想到權值線段樹維護

每次在權值線段樹中查詢\([k,n]\),在滿足條件\(1\)的情況下盡量往左走即可

那麼我們怎麼判斷是否滿足條件\(1\)呢?

我們可以發現條件\(1\)是關於位置的限制,所以我們在權值線段樹中儲存各個元素的位置並維護其最大值

那麼在查詢時按照以下的順序即可:

如果左子樹的位置最大值\(\geq r\),證明左子樹中一定有滿足條件的數,向左子樹查詢

否則如果右子樹的最大值\(\geq r\),向右子樹查詢

如果左右子樹都沒有,返回乙個極大值

在所有查詢結果中取乙個最小值即可

對於刪除操作,直接把其位置設為乙個極大值,因為只要詢問區間包含這個數,這個數必然是合法的

沒封裝,有點醜。。。

#include using namespace std;

const int n = 1e6 + 10;

const int add = 10000000;

int t, n, m, lstans;

int a[n], b[n], mx[n << 2];

inline int max(int x, int y)

inline int min(int x, int y)

void build(int root, int l, int r)

int mid = l + r >> 1;

build(root << 1, l, mid);

build(root << 1 | 1, mid + 1, r);

mx[root] = max(mx[root << 1], mx[root << 1 | 1]);

}void change(int root, int l, int r, int x)

int mid = l + r >> 1;

if (x <= mid)

change(root << 1, l, mid, x);

if (x > mid)

change(root << 1 | 1, mid + 1, r, x);

mx[root] = max(mx[root << 1], mx[root << 1 | 1]);

}int query(int root, int l, int r, int x, int y, int v)

int main() else

} }return 0;

}

2019CCPC網路選拔賽補題

hdu6703 題意就不說了,直接分析吧。對於1操作,a pos 1e7,但是我們每次詢問是 1,n 範圍內的,這個操作顯然就是把這個點給刪了。對於2操作,詢問 1,r 區間內 k且不等於a i 1 i r 的最小的數。題目做法如下 對位置建權值線段樹,每個結點表示乙個區間,每個結點維護乙個區間的位...

2019CCPC網路選拔賽簽到題題解

因為實力不濟,沒能通過網路賽拿到晉級的名額,心情沉重,故作此文記錄本次網路賽的點滴收穫。其中包含1001 1006 shuffle card 1007 windows of ccpc 1008 fishing master的題解。題目傳送門 題目分析 要找到使 ax orc a xor c axor...

2019ccpc哈爾濱補題

因為每個字串只能取乙個,剛開始是覺得全部列舉也不會超,後來想想列舉也要用深搜,所以就先記錄擁有各個字元的串,然後深搜 include using namespace std const int maxn 2e6 10 int t char s maxn vector int v 10 bool vi...