244 謎一樣的牛(樹狀陣列)

2021-09-25 22:00:23 字數 1650 閱讀 4877

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

現在這n頭奶牛站成一列,已知第i頭牛前面有ai

頭牛比它低,求每頭奶牛的身高。

輸入格式

第1行:輸入整數n。

第2…n行:每行輸入乙個整數ai

,第i行表示第i頭牛前面有ai

頭牛比它低。

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

輸出格式

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

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

資料範圍

1≤n≤105

輸入樣例:51

210輸出樣例:24

531分析:

在分析的時候,明確自己需要啥。然後,在不斷模擬的過程中,找到更簡便的方法,達到自己的目的。

這個題,我一波錯誤分析,wa飛了。xuxuxu

看到題目。很自然而然的相到從後面往前找。因為最後乙個的身高一定為

h[n] = a[n] + 1.

那麼前乙個的身高為多少呢?

h[n-1] = a[n-1] + 1 (if(a[n -1] < a[n]) 或者

h[n-1] = a[n-1] + 2 (if ( a[n -1] >= a[n])

這是容易得到的。

所以,我們

對於每個h[i] = a[i] + 1 + x.我就是因為這裡想錯了。我一開始想的是對於每個a[i]求一下他之前出現的個數有多少個。但是後面發現這並不行。

其實,我們由h[n-1]可以得到另外乙個思想:

對於每個h[i] 是不是在(1-n)這個序列(這個序列不包括已經安排了的身高)中找到第a[i] + 1大的那個數就好了呢。

故,我們的目的現在變成了,對於每個h[i] 在序列(1-n)中找到未出現過的身高的第a[i]+1大的值就可以了。

為了達到這個目的,通俗的想便是遍歷一次序列找到那個值。但是這樣很明顯超時。

那麼我們用乙個c陣列。c[i] 表示前i個數有多少個數是未被使用過的,這樣是可以的。

然後,我們便可以用二分或者倍增的方法求出第a[i] + 1大的那個數了。

如果i這個數被使用了,則要修改c陣列。這不就是樹狀陣列的單點修改嗎。

明確目的,通過方法解決目的。開展思維,證明可行性。

#include"stdio.h"

#include"string.h"

#include"algorithm"

using namespace std;

int n,a[100100];

int c[100010];

int h[100010];

int id[100010];

int s;

int lowbit(int x)

void add(int x,int v)

}int ask(int x)

return sum;

}int main()

for(int i = n; i >= 2; i --)

h[i] = l;

add(l,-1);

s -= l;

}h[1] = s;

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

printf("%d\n",h[i]);

}

謎一樣的牛 樹狀陣列

有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頭牛前面沒有牛,所以並沒有將...

ACwing 244 謎一樣的牛

時 空限制 1s 64mb 有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有aiai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2.n行 每行輸入乙個整數aiai,第i行表示第i頭牛前面有aiai頭牛比它低。注...