POJ 2352 Stars

好吧,我承认我在家没怎么写代码,集训第一天就脑残了. . . . . .兴致勃勃的写完一种n*log n的结果是n^2的,TLE了N遍. . . . . .

题意:对于一颗星星,有多少颗在它的左下方,它的等级就是多少,最后输出各个等级的数量有多少。

思路:因为题目中已经说了Y是按升序给出的,所以我们只要统计在当前这颗星星之前有多少颗的X是小于当前这一颗,然后就变成了一维线段树的查询与维护。

需要注意的地方就是,线段树的数组下表是从1开始的。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>

#define LL long long
#define PI (acos(-1.0))
#define EPS (1e-10)

using namespace std;

struct N
{
    int x,y;
}p[15010];

int st[150010];

void Init(int site,int l,int r)
{
    if(l == r)
    {
        st[site] = 0;
        return ;
    }

    int mid = (l+r)>>1;

    Init(site<<1,l,mid);
    Init(site<<1|1,mid+1,r);
}

int level[15010];

int query(int site,int l,int r,int L,int R)
{
    if(l == L && r == R)
    {
        return st[site];
    }

    int mid = (L+R)>>1;

    if(r <= mid)
        return query(site<<1,l,r,L,mid);

    if(mid < l)
        return query(site<<1|1,l,r,mid+1,R);

    return query(site<<1,l,mid,L,mid) + query(site<<1|1,mid+1,r,mid+1,R);
}

void updata(int site,int s,int L,int R)
{
    st[site]++;
    if(L >= R)
        return ;

    int mid = (L + R)>>1;

    if(s <= mid)
        updata(site<<1,s,L,mid);
    else
        updata(site<<1|1,s,mid+1,R);
}

int main()
{
    int n,i;

    scanf("%d",&n);

    memset(level,0,sizeof(int)*(n+2));

    Init(1,1,32001);

    for(i = 1; i <= n; ++i)
    {
        scanf("%d %d",&p[i].x,&p[i].y);
        level[query(1,1,p[i].x+1,1,32001)]++;
        updata(1,p[i].x+1,1,32001);
    }

    for(i = 0; i < n; ++i)
    {
        printf("%d\n",level[i]);
    }

    return 0;
}

你可能感兴趣的:(POJ 2352 Stars)