您的位置:首页 > 其它

jzoj 1979 【树状数组】 星星点灯

2017-03-03 11:57 369 查看
 天文学家经常要检查星星的地图,每个星星用平面上的一个点来表示,每个星星都有坐标。我们定义一个星星的“级别”为给定的星星中不高于它并且不在它右边的星星的数目。天文学家想知道每个星星的“级别”。

  

  例如上图,5号星的“级别”是3(1,2,4这三个星星),2号星和4号星的“级别”为1。

  给你一个地图,你的任务是算出每个星星的“级别”。

Input

  输入的第一行是星星的数目N(1<=N<=60000),接下来的N行描述星星的坐标(每一行是用一个空格隔开的两个整数X,Y,0<=X,Y<=32000)。星星的位置互不相同。星星的描述按照Y值递增的顺序列出,Y值相同的星星按照X值递增的顺序列出。

Output

  输出包含N行,一行一个数。第i行是第i个星星的“级别”

Sample Input

5

1 1

5 1

7 1

3 3

5 5

Sample Output

0

1

2

1

3

Data Constraint

解题思路:由于题目对输入x,y的限制,直接用树状数组求和x就好了,但要注意x可能=0,出现卡死的情况,所以维护树状数组的时候记得加1.

#include <cstdio>
#include <cstring>
#define F(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
int c[62236 ],n;
int lowbit(int x)  {  return x & -x;  }
int getsum(int num)
{
int sum = 0;
while(num > 0)
{
sum += c[num];
num -= lowbit(num);
}

return sum;
}
void update(int num)
{
while(num <= 32000)
{
c[num] ++;
num += lowbit(num);
}
}
int main()
{
freopen("data5.in","r",stdin);
freopen("star.out","w",stdout);
scanf("%d",&n);

memset(c,0,sizeof(c));
int x,y;
F(i,1,n)
{

scanf("%d%d",&x,&y);
printf("%d\n",getsum(x+1));

update(x+1);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: