題意:給出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...