1. 程式人生 > 實用技巧 >數星星 Stars 題解

數星星 Stars 題解

題目連結

分析

一道樹狀陣列,但坑點比較多。。。
首先在草稿紙上畫圖可以得知:星星的等級與\(x\)無關,至於\(y\)的大小有關,於是我們可以根據輸入順序一一將其插入樹狀陣列進行維護,此星星的等級其實就是在插入前以\(1\)~星星的\(y\)的星星數量和。

注意

星星的座標是從\((0, 0)\)開始存,但樹狀陣列不能夠維護,所以要提前將所有星星的\(x\)加上一。(如果在求和函式中把限度跳到0就會卡死迴圈我就錯了)

程式碼

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 3e5 + 5;

int x[MAXN], n, m, star[MAXN], t[MAXN];
int bit[MAXN];

int lowbit(int x) {
	return x & (-x);
}

void update(int k, int x) {
	for (int i = k; i <= MAXN; i += lowbit(i)) {
		bit[i] += x;
	}
}

int Sum(int k) {
	int ans = 0;
	for (int i = k; i; i -= lowbit(i)) {
		ans += bit[i];
	} 
	return ans;
} 

int main() {
//	freopen("star.in", "r", stdin);
//	freopen("star.out", "w", stdout);
	scanf ("%d", &n);
	for (int i = 1, y; i <= n; i++) {
		scanf ("%d %d", &x[i], &y);
		++x[i];
		m = max(m, x[i]);
	}
	for (int i = 1; i <= n; i++) {
		star[Sum(x[i])] ++;
		update(x[i], 1);
	}
	for (int i = 0; i < n; i++) {
		printf ("%d\n", star[i]);
	}
	return 0;
}