p1357 星星点灯(树状数组 ——二维数点问题)

题目

描述 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
经典问题

题解

听完大佬讲课后,发现题解写的是错的。。。。。
所以,重新写题解:(留在日后补。。。。。。。
1.

代码

#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,int k)
{
	while (x<=32000)
	{
		tree[x]+=k;
		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()+1,y=read();
		//为什么需要x+1,因为可能有x=0,而若把0带进lowbit函数,会发生lowbit(0)=0,会导致TLE大法 
		printf("%d\n",sum(x));
		add(x,1);
	}
	return 0;
}

你可能感兴趣的:(树状数组)