謎一樣的牛(樹狀陣列 二分)

2021-10-25 13:57:36 字數 2302 閱讀 3024

題目描述

有n頭奶牛,已知它們的身高為 1~n 且各不相同,但不知道每頭奶牛的具體身高。

現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。

輸入格式

第1行:輸入整數n。

第2…n行:每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。

(注意:因為第1頭牛前面沒有牛,所以並沒有將它列出)

輸出格式

輸出包含n行,每行輸出乙個整數表示牛的身高。

第i行輸出第i頭牛的身高。

資料範圍

1≤n≤105

輸入樣例:

512

10

輸出樣例:

245

31

對於做資料結構的題目,資料結構本身不難,難的是我們怎麼把他抽象成用資料結構操作。

題目資料給出每頭牛前面有幾頭牛比它矮,對於樣例來看

第1頭牛前面沒有牛、第2頭牛前面有1頭牛比他矮、第3頭牛前面有2頭牛比他矮、第4頭牛前面有1頭牛比他矮、第5頭牛前面有0頭牛比他矮。

資料 :0 1 2 1 0

我們正向不好看,倒著看。

最後一頭牛,前面沒有比他矮的,說明它是最矮的 。1、2、3、4、5,選擇1作為身高。

倒數第2頭牛,前面有1頭牛比他矮,說明它是剩餘身高中第二矮的。2、3、4、5,選擇3作為身高。

倒數第3頭牛,前面有2頭牛比他矮,說明它是剩餘身高中第三矮的。2、4、5,選擇5作為身高。

倒數第4頭牛,前面有1頭牛比他矮,說明它是剩餘身高中第二矮的。2、4,選擇4作為身高。

倒數第5頭牛,前面有0頭牛比他矮,說明它是剩餘身高中最矮的。2,選擇2作為身高。

答案即 2、4、5、3、1

所以,我們根據分析的結論可以得出,對於第i頭牛,他的身高=剩餘身高中第k+1矮的(k是前面比他矮的牛)。

邏輯操作

倒序遍歷每一頭牛

對於每一頭牛

在剩餘的身高中找第k+1小的。

刪除找到的身高

如果用二重迴圈肯定會tle。

查詢剩餘身高我們盡量希望是log級別的,因為我們要遍歷所有牛不能優化,查詢盡可能的更快。

所以查詢我們要使用二分查詢,二分查詢需要在乙個有序陣列裡,考慮到還有刪除操作,我們想到了樹狀陣列

刪除操作很簡單。

分析查詢:

我們把樹狀陣列的初始值附為1,代表這個身高還沒用過。

對於第i頭牛,他前面有m頭牛比他矮,二分查詢sum(x)>=m+1,也就是找第乙個》=m+1的下標,下標就是該牛的身高。

sum函式是樹狀陣列的字首和。

sum(1 ~ n)一定是乙個單調遞增的數,因為我們初始值為1,如果用過乙個身高,則變成0,所以無論怎麼變,sum(1 ~ n)一定是乙個遞增的數。

比如 :

剩餘身高 :有 1 2 3 4 5 (1、4被用過了)

樹狀陣列維護的陣列 為 0 1 1 0 1

sum函式維護的字首和為:0 1 2 2 3

如果我們找剩餘身高中第2矮的,二分查詢第乙個sum(x)的下標》=2的,下標3就是該牛的身高。

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

code:

#include

#include

#include

typedef

long

long ll;

const ll n=

1e5+10;

using

namespace std;

ll h[n]

,a[n]

,tr[n]

,ans[n]

;ll n;

ll lowbit

(ll x)

void

add(ll pos,ll x)

ll sum

(ll x)

intmain()

add(r,-1

);ans[i]

=r;}

for(

int i=

1;i<=n;i++

) cout<

}

樹狀陣列 二分 謎一樣的牛

有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2 n行 每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。注意 因為第1頭牛前面沒有牛,所以並沒有將...

樹狀陣列 二分查詢 謎一樣的牛

有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2 n行 每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。注意 因為第1頭牛前面沒有牛,所以並沒有將...

謎一樣的牛 樹狀陣列

有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2 n行 每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。注意 因為第1頭牛前面沒有牛,所以並沒有將...