这道题刚看的是时候认为可能用不了树状数组,后来看到一份梳妆数组资料中发现有这道原题,发现自己是在太弱了。题目中已经为你排号序,你所需要做的是计算每个点之前有几个点的横坐标不小于当前点。树状数组只能计算去区间和,而不能比较大小,肿么办?原来是用到了哈希的思想,。。。。用a[t]表明有多少个星星的x坐标为t。。(程序中可以省略此数组),然后用梳妆数组计算a[1]到a[t]之间的和即可。。。然而,很快把程序交上去之后,发现无线WA,搞不懂。。。。
后来看了PKU的discuss中找到了答案,原来题目中给出0<=x<=32,000。。。。而树状数组显然不能处理0的情况,好吧,只能把横坐标+1。。。。。这道题对于初学者来讲,虽然很坑爹,但是非常经典。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int n;
const int N=16000;
const int M=33000;
int a[M],c[N];
int lowbit(int t)
{
return t&(-t);
}
void insert(int t,int d)
{
while (t<=M)
{
a[t]+=d;
t+=lowbit(t);
}
}
int getsum(int t)
{
int zs=0;
while (t>0)
{
zs+=a[t];
t-=lowbit(t);
}
return zs;
}
int main()
{
int i,x,y,p,n;
while (scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
for (i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
insert(x+1,1);
p=getsum(x+1)-1;
c[p]++;
}
for (i=0;i<n;i++) printf("%d\n",c[i]);
}
return 0;
}