p1357 星星点灯

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84831826

题目

描述 Description
天文学家经常要检查星星的地图,每个星星用平面上的一个点来表示,每个星星都有坐标。我们定义一个星星的“级别”为给定的星星中不高于它并且不在它右边的星星的数目。天文学家想知道每个星星的“级别”。
             * 5
           * 4
         *1  * 2 *3
例如上图,5号星的“级别”是3(1,2,4这三个星星),2号星和4号星的“级别”为1。

给你一个地图,你的任务是算出每个星星的“级别”。
输入格式 Input Format
输入的第一行是星星的数目N(1<=N<=60000),接下来的N行描述星星的坐标(每一行是用一个空格隔开的两个整数X,Y,0<=X,Y<=32000)。星星的位置互不相同。星星的描述按照Y值递增的顺序列出,Y值相同的星星按照X值递增的顺序列出。
输出格式 Output Format
输出包含N行,一行一个数。第i行是第i个星星的“级别”
样例输入 Sample Input

5
1 1
5 1
7 1
3 3
5 5

样例输出 Sample Output

0
1
2
1
3

时间限制 Time Limitation
1s
注释 Hint
1s
来源 Source
经典问题

题解

看见了坐标,以为是二维树状数组,然后发现。。。。。。是错的。改成了一维树状数组,嗯,基本上又是一道板子题,只不过函数传参得改一下。参考代码啦!!!

代码

#include<bits/stdc++.h>
using namespace std;
const int maxnum=6e4+1;
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
	return num*f;
}
int n,tree[maxnum];
int lowbit(int x)
{
	return x & -x;
}
void add(int x)
{
	while (x<=32000)
	{
		tree[x]++;//注意这里
		x+=lowbit(x);
	}
}
int sum(int x)
{
	int ans=0;
	while (x)
	{
		ans+=tree[x];
		x-=lowbit(x);
	}
	return ans;
}
int main()
{
	n=read();
	for (int i=1;i<=n;++i)
	{
		int x=read(),y=read();
		printf("%d\n",sum(x+1));//就是这里
		//为什么加1,因为可能有x=0啊,把0带进去,会导致lowbit函数直接挂掉!!!!
		add(x+1);//还有这里
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84831826