问题 B: 数星星Stars
时间限制: 1 Sec 内存限制: 128 MB
提交: 33 解决: 14
[提交][状态][讨论版][命题人:quanxing][Edit] [TestData]
题目链接:http://acm.ocrosoft.com/problem.php?cid=1688&pid=1
题目描述
天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标。 如果一个星星的左下方(包含正左和正下)有k颗星星,就说这颗星星是k级的.
比如,在下面的例图中,星星5是3级的(1,2,4在它左下)。 星星2,4是1级的。例图中有1个0级,2个1级,1个2级,1个3级的星。
【编程任务】
给定星星的位置,输出各级星星的数目。
给定N个点,定义每个点的等级是在该点左下方(含相等)的点的数目,试统计每个等级有多少个点。(1<=N<=15 000,0<=x<=32 000,0<=y<=32 000)
输入
第一行一个整数N(1<=N<=15 000),表示星星的数目。
接下来N行给出每颗星星的坐标,两个整数x,y。
不会有星星重叠。星星按Y坐标增序给出,Y坐标相同的按X坐标增序给出。
输出
N行,每行一个整数,分别是0级,1级,2级……N-1级的星星的数目
样例输入
5
1 1
5 1
7 1
3 3
5 5
样例输出
1
2
1
1
0
思路:模拟树状数组就行了,不过要注意录入x时要x++,因为lowbit(0)=0。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000000
int A[maxn], C[maxn], result[maxn];
int n, m;
int lowbit(int t)//t转换为二进制后,有末尾连续0共k个,返回2^k次方
{
return t & -t;
}
void add(int x, int y)//单点修改
{
for (int i = x; i <= 32005; i += lowbit(i))
{
C[i] += y;
}
}
int sum(int x)//区间求和
{
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
{
ans += C[i];
}
return ans;
}
int main()
{
scanf("%d",&m);
int t = m;
while (t--)
{
int x, y;
scanf("%d %d", &x,&y);
result[sum(x+1)]++;//(x+1)是防止add(0,1),sum(0)死循环,因为lowbit(0)=0
add(x+1, 1);
}
for (int i = 0; i < m; i++)
{
//cout << 11 << endl;
printf("%d\n", result[i]);
//cout << result[i] << endl;
}
}