题目地址:http://poj.org/problem?id=2352
题意:在 (0<=x,y<=32000)范围内有15000个点,问每个点存在几个比它的横纵坐标都小于等于的点。注意输出依次是存在满足0,1,2...个点的个数。
分析:对于第i个点存在几个满足条件的点,只需统计一下x<=xi的点里有几个y<=yi的点。
因此,每次按照点坐标的顺序,查找一次y<=yi,加入一个y坐标。
我最初是用的二叉排序树做的,因为可能达不到平衡的状态,所以各种被T。正确的是用树状数组,严格保证每次查询和插入是nlogn的,事实证明树状数组编程简单又快,是解决这个问题的好办法。注意坐标是0开始的。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
struct node
{
int x,y;
}d[16000];
int tr[34000];
int n;
int ans[16000];
int low(int p)
{
return p&(-p);
}
void insert(int p)
{
while (p<33005)
{
tr[p]++;
p+=low(p);
}
}
int find(int p)
{
int ans=0;
while (p)
{
ans+=tr[p];
p-=low(p);
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
while (~scanf("%d",&n))
{
for (int i=0;i<n;i++)
{
scanf("%d%d",&d[i].y,&d[i].x);
d[i].y++;
}
memset(tr,0,sizeof(tr));
for (int i=0;i<n;i++)
{
ans[find(d[i].y)]++;
insert(d[i].y);
}
for (int i=0;i<n;i++)
printf("%d\n",ans[i]);
}
return 0;
}