PKU2352

题目链接:http://poj.org/problem?id=2352

分析:假如把数据进行排序之后遍历,则时间复杂度会很高,多达O(n),因为可以抽象为区间求和问题,所以可以使用线段树来解决问题,初始化的时间复杂度为nlog(n),查询时间为O(1)。

思路:因为是在左下方,所以可以先按x排序,若x相同,则y小的在后面的方式排序,需注意下标应从1开始。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Point{int x,y;}a[100005];
int n,c[100005]={0},Ans[100005]={0},MaxY;//Ans[i]第i+1类星星的数量
bool cmp(const Point &a,const Point &b)
{  return (a.x<b.x)||(a.x==b.x&&a.y<b.y);}
void Read()
{  int i;
   cin>>n;MaxY=0;
   for(i=1;i<=n;i++)
   {  scanf("%d%d",&a[i].x,&a[i].y);
      a[i].x++; a[i].y++;
      MaxY=max(MaxY,a[i].y);
   }
}
int Lowbit(int i){return i&(-i);}
void Add(int t){for(int i=t;i<=MaxY;i+=Lowbit(i))c[i]++;}
int Sum(int t)
{  int i,s=0;
   for(i=t;i>0;i-=Lowbit(i))s+=c[i];
   return s;
}
void Solve()
{  int i;
   sort(a+1,a+n+1,cmp);//按照x从小到大排序,x相同y从小到大
   for(i=1;i<=n;i++){Ans[Sum(a[i].y)]++;Add(a[i].y);}
   for(i=0;i<=n-1;i++)cout<<Ans[i]<<endl;
}
int main()
{  Read();
   Solve();
}

猜你喜欢

转载自blog.csdn.net/qq_36353434/article/details/81394119