HDU-4217(樹狀數組)

題意就是在1~N中每次找到第k小的數並刪除,範圍固定第k小的數,就是樹狀數組或者線段樹的應用,一個細節是結果需要用long long,因爲262144*(262144+1)/2超過了32位表示範圍。


#include <cstdio>
#include <cstring>
#define MAX	262200

int n, q, c[MAX];
inline int lowbit(int x){
	return x & -x;
}
void add(int x, int v)
{
	for(; x <= n; x += lowbit(x)) c[x] += v;
}
int query(int x)
{
	int s = 0;
	for(; x; x -= lowbit(x)) s += c[x];
	return s;
}
int find(int kth)
{
	int l = 0, r = n;
	while(l+1 < r){
		int m = (l+r) >> 1;
		if(query(m) >= kth) r = m;
		else l = m;
	}
	return r;
}

int main()
{
	int t = 1, test, k;
	long long res;
	for(scanf("%d", &test); t <= test; ++t){
		scanf("%d%d", &n, &q);
		memset(c+1, 0, n*sizeof(int));
		for(int i = 1; i <= n; ++i) add(i, 1);
		res = 0;
		while(q--){
			scanf("%d", &k);
			k = find(k);
			res += k;
			add(k, -1);
		}
		printf("Case %d: %lld\n", t, res);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章