poj2352 - Stars(树状数组)

题意:给定每个星星(x,y)的坐标求该满足条件(x'<=x&&y'<=y)的已存在的星星(x', y')的个数。

思路:题目的输入数据很有特色就是按行输入,

例如:

5
0 1
5 1
7 1
3 3
5 5

就是第一行的3个坐标优先,然后是第二行的,然后是。。。。。

所以我们求满足条件的星星数目便无须关心纵坐标了。

可以直接用线段树写出来,也可以离散化后在写出来,总之要注意x=0的情况,

离散化的时候由于排序失误还wa了一次。

原因是排序过程如果不规定原序作为次级排序依据的话,最后出来的结果很可能会出现相等数字的顺序跟原序不同的状况;

离散化代码:

#include <cstdio>
#include <algorithm>
using namespace std;
#define M 15005
#define lowbit(x) -x&x
struct Node{
    int v, x;
};
Node a[M];
int n, c[M], r[M], ans[M];
int comp(const Node p, const Node q) { return p.v==q.v?p.x<q.x:p.v<q.v; }
void add(int x)
{
    while(x<=n)
    {
        c[x]+=1;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ret = 0;
    while(x>0)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
int main ()
{
    int t;
    scanf("%d",&n);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d %*d",&t);
        a[i].v = t;
        a[i].x = i;
    }
    sort(a+1,a+n+1,comp);
    for(int i = 1; i <= n; ++i)
        r[a[i].x] = i;
    for(int i = 1; i <= n; ++i)
    {
        ++ans[sum(r[i])];
        add(r[i]);
    }
    for(int i = 0; i < n; i++)
        printf("%d\n",ans[i]);
    return 0;
}



未离散化代码:

#include <cstdio>
#define M 15005
#define N 32005
#define lowbit(x) -x&x
int n, c[N], ans[M];
void add(int x)
{
    while(x<=32004)
    {
        c[x]+=1;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ret = 0;
    while(x>0)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
int main ()
{
    int t;
    scanf("%d",&n);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d %*d",&t);
        ++ans[sum(t+1)];
        add(t+1);
    }
    for(int i = 0; i < n; i++)
        printf("%d\n",ans[i]);
    return 0;
}


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