题意:有很多给定坐标的星星,求每个星星左下方的星星数。
题解:用树形数组解。因为输入时y是升序,只要x1 >= x2 就可行。所以可以将二维视作一维,只考虑x就可以了。另外需要注意的是,树形数组不能从0开始,否则函数lowbit,和函数update死循环。这个问题可以将输入的x平移一个单位(即加1)来解决。
#include <memory>
#include <cstdio>
int n, lev[16000],c[33000];
int lowbit ( int t )
{
return t & ( t^(t-1) ); // t & ( -t );
}
void update ( int t )
{
while ( t <= 32001 )
{
++c[t];
t += lowbit(t);
}
}
int getSum ( int t )
{
int sum = 0;
while ( t >= 1 )
{
sum += c[t];
t -= lowbit(t);
}
return sum; // 返回的sum加进了星星本身,所以最后从1开始输入,但结果依然正确。
}
int main()
{
int i,x,y;
scanf("%d",&n);
memset(lev,0,sizeof(lev));
memset(c,0,sizeof(c));
for ( i = 1; i <= n; ++i )
{
scanf("%d%d",&x,&y);
++x;
update(x); //因为y是升序的,后面输入的星星一定不在此星星的左下方,所以后面的输入对现在求出的结果不产生影响
lev[getSum(x)]++;
}
for ( i = 1; i <= n; ++i )
printf("%d\n",lev[i]);
return 0;
}