hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541

题目意思:有 N 颗星星,每颗星星都有各自的等级。给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定。计算出每个等级(0 ~ n-1)的星星各有多少颗。

      我只能说,题目换了一下就不会变通了,泪~~~~

      星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴!

      按照题目输入,当前星星与后面的星星没有关系。所以只要把 x 之前的横坐标加起来就可以了。不过要注意树状数组是从下标 1 开始算的,而输入有可能 是 0(横坐标x = 0),所以题目中当x = 0 时,要执行 x++,相当于所有坐标右移一位,但是没有改变坐标间的相对位置。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 32000 + 5;
int c[maxn], level[maxn];

int lowbit(int x)
{
    return x & (-x);
}

void update(int pos)
{
    while (pos < maxn)
    {
        c[pos]++;
        pos += lowbit(pos);
    }
}

int sum(int x)
{
    int s = 0;
    while (x > 0)
    {
        s += c[x];
        x -= lowbit(x);
    }
    return s;
}

int main()
{
    int n, x, y;
    while (scanf("%d", &n) != EOF)
    {
        memset(c, 0, sizeof(c));           // 没了这两行会
        memset(level, 0, sizeof(level));   // runtime error !

        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &x, &y);
            level[sum(x+1)]++;    // 为了防止出现x = 0的情况,所有 x 右移一位,保持横坐标相对次序不变
            update(x+1);        // 下标为x + 1的位置加上1
        }
        for (int i = 0; i < n; i++)
            printf("%d\n", level[i]);
    }
    return 0;
}


ps: 每次修改的是一个点(在它下面或者左边的点有多少个),所求的是关于某段区间(统计level)
posted @ 2014-08-20 22:38  windysai  阅读(234)  评论(0编辑  收藏  举报