poj2352——二维偏序+树状数组

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

目录

Description

Input

Output

Sample Input

Sample Output


 

 Description

天文学家经常研究星图,星图上的星星由平面上的点表示,每颗星星都有笛卡尔坐标。一颗星星的等级是指该星星左下方的星星的数量.
poj2352——二维偏序+树状数组_第1张图片poj2352——二维偏序+树状数组_第2张图片
例如,查看上图所示的地图,5号星的等级为3(左下方有1、2、4号星),2号星和4号星的等级为1。在这张地图上有一颗0级的星星,两颗1级的星星,一颗2级的星星,和一颗3级的星星。
你需要写一个程序来计算给定星图上每个等级的星星数量
 

Input

输入的第一行包括了星星的数量N (1<=N<=15000),下面N行描述了每颗星星的坐标(每一行由一个空格分隔两个整数X和Y组成, 0<=X,Y<=32000)。每一个点只会存在一颗星星。星星以Y坐标的升序排列。Y坐标相等的恒星按X坐标的升序排列。

Output

输出应该包括N行,每行一个数字。第一行为等级是0级的星星数量,第二行为等级是1级的星星数量,以此类推,最后一行为等级是N-1级的星星数量。

Sample Input

5
1 1
5 1
7 1
3 3
5 5

Sample Output

1
2
1
1
0

 

题解:

经典的二维偏序问题,而且根据输入数据的限制,相当于降了一维,因为,默认输入的数据是 以Y坐标的升序排列,Y坐标相等的恒星按X坐标的升序排列。所以我们只需要找到在当前位置之前,且x坐标小于当前位置的x坐标的恒星的个数。

因此我们只需要考虑x坐标就行了,维护一个树状数组表示一段区间内小于当前位置的恒星的个数,常规的树状数组题目。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PI atan(1.0)*4
#define e 2.718281828
#define rp(i,s,t) for (i = (s); i <= (t); i++)
#define RP(i,s,t) for (i = (t); i >= (s); i--)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define push_back() pb()
#define fastIn                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
using namespace std;
inline int read()
{
    int a=0,b=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            b=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        a=(a<<3)+(a<<1)+c-'0';
        c=getchar();
    }
    return a*b;
}
inline void write(int n)
{
    if(n<0)
    {
        putchar('-');
        n=-n;
    }
    if(n>=10)
        write(n/10);
    putchar(n%10+'0');
}
const int N=1e5+7;
int sum[N],ans[N];
int n;
int lowbit(int x){
    return x&(-x);
}
int query(int i){
    int res=0;
    while(i>0){
        res+=sum[i];
        i-=lowbit(i);
    }
    return res;
}
void update(int i,int val){
    while(i<=N){
        sum[i]+=val;
        i+=lowbit(i);
    }
}
int main(){
	n=read();
    int i;
    rp(i,0,n-1){
        int x=read(),y=read();
        x++;
        ans[query(x)]++;//查询当前恒星之前,且x坐标小于当前位置的x坐标的横向个数,并记录。
        update(x,1);//插入当前恒星,更新维护的树状数组
    }
    rp(i,0,n-1)
        printf("%d\n",ans[i]);
	return 0;
}

 

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