题解 线段树 POJ 2352

题意:给出n个点的平面二维坐标,对于每个坐标,如果这个坐标跟(0,0)形成的矩形内包 含的点数为 k (包含边界,但不包含坐标本身),那么这个坐标就是 level k。输出 level 0 – leveln-1的点数分别是多少。

n个点按照纵坐标y升序给出。

做法:见代码。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX=30000;
int b[MAX],dat[4*MAX],a[MAX];
void build(int p,int l,int r,int x)
{//创建一个线段树,计算每个区间内的星星数。
    if(l==r) {dat[p]++;return;}
    int mid=(l+r)/2;
    if(mid>=x)build(p*2,l,mid,x);
    if(mid<x)build(p*2+1,mid+1,r,x);
    dat[p]=dat[p*2]+dat[p*2+1];
}
int find(int p,int l,int r,int x,int y)
{//寻找在区间内(x,y)的星星总数
    if((x<=l)&&(r<=y))return dat[p];
    int mid=(l+r)/2;
    if(mid>=y)return find(p*2,l,mid,x,y);
    if(mid<x)return find(p*2+1,mid+1,r,x,y);
    int t=find(p*2,l,mid,x,y)+find(p*2+1,mid+1,r,x,y);
    return t;
}
int main()
{
    int i,n,maxn=0;
    scanf("%d",&n);
    memset(dat,0,sizeof(dat));
    memset(b,0,sizeof(b));
    memset(a,0,sizeof(a));
    for(i=1;i<=n;i++)
    {
        int y;
        scanf("%d%d",&b[i],&y);
        if(b[i]>maxn)maxn=b[i];
    }
    for(i=1;i<=n;i++)
    {
        build(1,0,maxn,b[i]);
        a[find(1,0,maxn,0,b[i])-1]++;
    }
    for(i=0;i<n;i++)
    {
        printf("%d\n",a[i]);
    }
    return 0;
}


错误:RE:线段树数组开的限度过小,导致RE。

posted on 2014-07-25 11:43  一锅土豆  阅读(115)  评论(0编辑  收藏  举报