HDU1556 Color the ball【树状数组】【区间更新】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1556


题目大意:

N个气球排成一排,从左到右编号为1~N,给N组数据,每次给2两个整数s,e,表示从s到e将

气球涂色。当涂到N次以后已经忘记了第i个气球被涂过几次颜色了。现在来计算出每个气球被

涂了几次颜色,并输出出来。


思路:

典型的更新区间,单点求值问题。直接模拟会超时,考虑用树状数组来做。单点更新中,树状

数组表示区间的和。在区间更新中,树状数组表示单个元素的变化。

这道题中,区间(s,e)加1表示将s到e的气球涂色,先进行操作Update(s,1),表示将s~N个气

球全部涂一次颜色,再进行操作Update(e+1,-1),表示将e+1的气球去除一次涂色。这样就

表示将区间(s,e)的气球涂色了。查询Query(i)表示第i个气球被涂颜色的次数。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100010;

int N,Tree[MAXN];

int Lowbit(int i)
{
    return i & (-i);
}

void Updata(int i,int x)
{
    while(i <= N)
    {
        Tree[i] = Tree[i] + x;
        i = i + Lowbit(i);
    }
}

int Query(int n)
{
    int sum = 0;
    while(n > 0)
    {
        sum += Tree[n];
        n = n - Lowbit(n);
    }
    return sum;
}

int main()
{
    while(cin >> N && N)
    {
        memset(Tree,0,sizeof(Tree));
        for(int i = 0; i < N; ++i)
        {
            int s,e;
            cin >> s >> e;
            Updata(s,1);
            Updata(e+1,-1);
        }

        for(int i = 1; i < N; ++i)
            printf("%d ",Query(i));
        printf("%d\n",Query(N));
    }

    return 0;
}


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。