题目描述:
天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标。如果一个星星的左下方(包含正左和正下)有 kk颗星星,就说这颗星星是 kk 级的。
一句话题意 给定 nn 个点,定义每个点的等级是在该点左下方(含正左、正下)的点的数目,试统计每个等级有多少个点
输入
第一行一个整数 N,表示星星的数目;
接下来 N 行给出每颗星星的坐标,坐标用两个整数 x,yx,y 表示;
不会有星星重叠。星星按 yy坐标增序给出,yy 坐标相同的按 xx 坐标增序给出。
输出
N 行,每行一个整数,分别是00 级,11 级,22 级,……,N−1N−1 级的星星的数目。
样例输入
5
1 1
5 1
7 1
3 3
5 5
样例输出
1
2
1
1
0
提示
对于全部数据,1≤N≤1.5×10^4 ,0≤x,y≤3.2×10^4 ,1≤N≤1.5×10^4 ,0≤x,y≤3.2×10^4
分析
这道题我们就直接讲思路吧~
我们首先可以分析到,我们最终的答案其实与 y 无关,至于为什么,博主就留下一个疑问,让读者们自己去演算一下吧。所以,我们就直接可以用一个 BIT 来维护就好了。我还是把注释写在代码上。
代码
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 15005, MAXX = 32005;//注意不要开大了
int ans[MAXN], bit[MAXX];
int n;
int Lowbit(int x) {
return x & (-x);
}
void Update(int index) {
for (int i = index; i <= MAXX; i += Lowbit(i)) {
bit[i] ++;//只加一
}
}
long long Sum(int index) {
long long sum_ = 0;
for (int i = index; i >= 1; i -= Lowbit(i)) {
sum_ += bit[i];
}
return sum_;
}
//常规操作
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
int a, b;
scanf("%d %d", &a, &b);
ans[Sum(a + 1)] ++;//因为 k 等星不包括自己,所以我们在这里处理一下
Update(a + 1);//存入
}
for (int i = 0; i < n; i++) {
printf("%d
", ans[i]);//输出
}
return 0;
}