题目大意:地图上有N个星星,一颗星星的等级就是横坐标不比他大,纵坐标不比他大的星星个数,
输入:N(1<=N<=15000)
第i颗星星的横坐标X 纵坐标Y(共N行,按照Y从小到大输入,Y相同时按照X从小到大 ,0<=X,Y<=32000)
输出:level0的星星个数
level1的星星个数
...
levelN-1的星星个数
分析:树状数组的应用。对于规定的输入方式,一个星星的等级数就是在它前面输入的x坐标小于等于他的星星个数。暴力会超时,所以需要一种数据结构记录所有星星的x坐标,并且方便求出横坐标在0~x的星星的总数量。每次在树状数组中插入x坐标更新即可。
需要注意的是,树状数组中下标为0的地方不可用,所以输入的x坐标要加1。
代码:转载自http://blog.csdn.net/shuangde800/article/details/8175139
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 32005;
int c[MAXN],level[MAXN],n;
int lowbit(int x){return x & (-x);}
// 求前n项的和
int sum(int n){
int sum = 0;
while(n > 0){
sum += c[n];
n -= lowbit(n);
}
return sum;
}
// 增加某个元素的大小
void add(int x){ //树状数组从下往上更新update
while(x <= MAXN){
++c[x];
x += lowbit(x);
}
}
int main(){
int n,x,y;
while(~scanf("%d",&n)){
memset(level, 0, sizeof(level));
memset(c, 0, sizeof(c));
for(int i=0; i<n; ++i) {
scanf("%d%d",&x,&y);
++x; //树状数组下标从1起,所以所有x坐标都加1
level[sum(x)]++; //统计横坐标在0~x的星星个数,即这个星星的等级数
add(x); //将这个星星也加进来
}
for(int i=0; i<n; ++i)
printf("%d\n",level[i]);
}
return 0;
}