题意
给你n个星星 (1<=N<=15000)和每个星星的坐标x,y(0<=X,Y<=32000),每个坐标不相同,且给出的坐标是按列序升序排列,列序相同则按行序升序排列。定义星星的等级是该星星左下角的星星个数(包括正下和正右),最后要你输出等级从0到n的星星个数。
题解
因为按给出的坐标的规则,前面的点一定在后面点的左面或者与它同列。所以该星星的等级即是前面星星中行序比它小的星星个数。这里有一个trick点,我树状数组总结里面提过,代码注释里会说。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 32005;
int n,c[maxn],ans[maxn];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<maxn)
{
c[x]++;
x += lowbit(x);
}
}
int query(int x)
{
int ans = 0;
while(x>0)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int x,y;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
ans[query(x+1)]++; //trick点就是行序要加1,不然x可能为0,导致更新的时候无限循环
update(x+1);
}
for(int i=0;i<n;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}