题目大意:
给你一个二维的坐标系(32000*32000),里面有n(15000)个点,告诉你每个点的坐标(各个点各不相同)。定义:
注:坐标点以y轴坐标的升序给出,y坐标相同的点以x轴坐标的升序给出。
分析:
这个题一开始想要用二维树状数组来做,但是觉得太麻烦了,去网上看了一下别人的思路,发现了一个很巧妙的地方。因为输入的时候是按照一定的升序顺序输入的,也就是一行一行输入,那么,其实,这些星星在一行上也是一样的(假设这些星星可以重合)。也就是说,在y=0的时候,输入一个点的坐标,那这个星星的左面有多少个点是已经算出来了的,用树状数组只需要log32000的时间。然后就是关键了,到了输入y=1行的点的坐标的时候,直接还是把它记录到y=0的那一行上面去,然后再用树状数组来求出该点的level值,时间复杂度还是log32000。综合时间复杂度为15000*log32000;
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int tree[40000]={0};
int num[40000]={0};
int n;
int lowbit(int x)
{
return (-x)&x;
}
void add(int x,int t)
{
while(x<=32010)
{
tree[x]+=t;
x=x+lowbit(x);
}
}
int sum(int x)
{
int s=0;
while(x>0)
{
s+=tree[x];
x=x-lowbit(x);
}
return s;
}
int main()
{
while(cin>>n)
{
memset(tree,0,sizeof(tree));
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++;
num[sum(x)]++;
//cout<<sum(x)<<endl;
add(x,1);
}
for(int i=0;i<n;i++)
{
cout<<num[i]<<endl;
}
}
}
后注:
注意坐标范围是[0,32000],但是树状数组里不能有0,所以把x整体加1。