题意:给出n个星星的坐标,将这n个星星分为0~n-1这n个等级,第0等级表示这颗星星的左下角没有其他星星,第一等级表示这颗星星的左下角有一颗星星......以此类推,问每个等级的星星有多少个??
分析:本题中已经明确说明y坐标非递减,所以在计算每颗星星左下角有多少个星星的时候,其实只需要记录它的左边有多少课星星就ok了,那么就把这些星星全都看成是在x轴上的星星,然后利用树状数组,对于每一个处在位置为x的星星,他会与它前面的星星一起为Sum(x+1)等级的星星有一份贡献,同时,比x+1更大的坐标处是否有星星是不确定的,所以只能暂时更新sum[i]而不能确定其他level.
参考代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 15010;
const int maxm = 32010;
int n;
int sum[maxm];
int level[maxn];
//清零x的二进制高位
inline int lowbit( int x)
{
return x&-x;
}
//表示到x以内有多少在它左下角的
int Sum( int x)
{
int ans = 0;
while( x)
{
ans += sum[x];
x -= lowbit(x);
}
return ans;
}
//x-1会影响右上角的数量
void Update( int x)
{
while( x < maxm)
{
sum[x]++;
x += lowbit(x);
}
}
int main()
{
while( ~scanf("%d",&n))
{
memset(sum,0,sizeof(sum));
memset(level,0,sizeof(level));
int x,y;
for( int i = 0; i < n; i++)
{
scanf("%d%d",&x,&y);
level[Sum(x+1)]++;
Update(x+1);
}
for( int i = 0; i < n; i++)
printf("%d\n",level[i]);
}
return 0;
}