AcWing 1265. 数星星
原题链接
中等
作者:
Fairy2.0
,
2025-01-13 21:56:32
,
所有人可见
,
阅读 1
#include <iostream>
#include <algorithm>
using namespace std;
//因为输入的坐标是按照纵坐标为第一关键词,横坐标为第二关键词(如果没有需要自己排序)
//那么对于当前的坐标的纵坐标一定是已经输入的坐标中最大的
//对于后面输入的坐标来说,只有2中情况
//第一种:纵坐标和当前这个坐标的纵坐标一样,但是横坐标一定大于当前这个坐标(因为坐标不会重叠)
//第二种: 纵坐标大于当前这个坐标的纵坐标,横坐标随便
//这2个种情况的坐标对应当前这个点来说,都不可能出现在这个点的左下方
//所以当前这个点只要考虑前面已经输入的点的坐标即可
//前面已经输入的点的纵坐标一定小于等于当前这个点的纵坐标
//所以只要看前面的点的横坐标
//横坐标小于等于当前这个点的横坐标的点就是位于当前这个点的左下方
//所以用一个数组存每个横坐标的点的数量
//对于当前这个点来说,横坐标小于等于当前这个点的横坐标的个数
//就是数组中1到x的和(x为当前这个点的横坐标)
//再把当前这个点加入到数组中,那么数组的值会发生变化
//所以可以用树状数组
const int N = 32010;
int a[N]; //原数组
int tr[N]; //树状数组
int level[N]; // level[i]表示等级为i的星星的个数---就是该点的等级
int n;
int lowbit(int x){
return x & -x;
}
void add(int a){
//这里不能小于n,因为树状数组存的是原数组某一段区间的和
//原数组的a[i]表示的是横坐标为i的星星个数
//所以要用N
for (int i = a;i < N;i += lowbit(i)){
tr[i] ++;
}
}
int sum(int a){
int s = 0;
for (int i = a;i;i -= lowbit(i))
s += tr[i];
return s;
}
int main (){
cin >> n;
for (int i = 0;i < n;i++){
int x = 0;
int y = 0;
scanf ("%d %d" , &x , &y);
x++; //树状数组的下标从1开始
int s = sum(x); //求下标为1到x的和---和就是当前这个星星的等级
level[s] ++; //等级为s的星星加1个
//把当前点加入
add(x);
}
for (int i = 0;i < n;i++){
cout << level[i] << endl;
}
return 0;
}