POJ 2352 樹狀陣列(線段樹)

2021-07-04 17:21:55 字數 1293 閱讀 2177

題意:給出n個點的座標(n<=15000),座標範圍為[1,32000],最後讓你輸出ans[i],表示有ans[i]個點左下方有i個點。

一開始直接寫的二維樹狀陣列,記錄乙個矩陣,如果(x,y)有點就是1,沒有點就是0,那麼我們可以輕易求出(1,1)到(x,y)共有多少點,不過這樣就爆了10倍記憶體。(1k == 256 int型整數)

然而後來才注意到:題目輸入是按照y座標從小到大輸入的。(英語水平很重要tat)

y座標按照從小到大輸入,所以可以只用一維的樹狀陣列,只需要記錄橫座標上1到x有多少個點即可。需要離散化,一開始寫的沒有離散化的t掉了。

**:

#include 

#include

#include

#define lowbit(x) x&-x

using

namespace

std;

int n, m, ans[15005], x[15005], y, f[32005];

struct start[15005];

bool cmp(star a, star b)

void add(int x)

int sum(int x)

int main()

sort(t+1, t+n+1, cmp);

int cnt = 1;

x[t[1].num] = 1;

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

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

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

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

}

有細節需要注意的是,空間用一維樹狀陣列的區別就是**裡標五角星的那個for迴圈,如果是二維的話應該是這麼寫的:

for(int i = 1; i

<= n; i++)

add(t[i].x, t[i].y);

for(int i = 1; i

<= n; i++)

這個需要實際理解一下左下方的含義,(x,y)的左下方的意思是(1,1)到(x,y)的矩形內的範圍(除了自己),所以在一維的計算中是ans[sum(x[i])-1]++, 二維就是sum(x-1, y) + sum(x, y-1) - sum(x-1, y-1) (當然二維也可以是sum(x,y)-1),二維的兩種寫法都很好理解,一維的就只有那一種寫法(sum(x[i]-1)是不對的,因為有可能會有x座標相同的,y座標比當前點小的點,而它們在一維的樹狀陣列中都被記錄成同乙個x座標),需要好好體會一下。

Poj2352 樹狀陣列或線段樹

確定星星的等級 就是他左下方星星的數目 又因為星星本來就是從左下到右上輸出的。所以直接搞就好。其實就是輸入乙個數 求之前小於等於這個數的數量x 然後a x 然後統計a x include include include include const int maxn 35002 const int n...

poj2352 樹狀陣列 線段樹嘗試失敗

啊啊啊,剛學線段樹,用線段樹寫這題不斷的tle!我自己弄了15000個資料,秒算的,結果還是說我tle,搞了2個小時沒看出 能超時 然後用之前學的樹狀。十分鐘就搞定了,兩種 都先放這裡,線段樹那個以後再拿出來看看 tle 樹狀陣列解法 include includeusing namespace s...

poj 2352 樹狀陣列

這道題好像被賤做了,看起來像二維的樹狀陣列,其實只是一維的,可能是資料太大了,矩陣開不那麼大,因為題意是求乙個矩陣中做它左下部分的個數,而去輸入的順序是按y公升序,後x公升序輸入。其實如果不按這個順序可以下排序。然後就是一維的樹狀陣列的思路了。轉個圖,可以知道它的這陣列性質了 include inc...