【差分数组】Color the ball

题意:http://acm.hdu.edu.cn/showproblem.php?pid=1556
N个气球排成一排,从左到右依次编号为1,2,3…N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
N <= 100000,1 <= a <= b <= N

差分数组简介:
即维护一个数组d[] ,里面记录原数组每一项与前一项的差值,那么原数组中的每一个数都可以用d数组中对应的前缀和表示。再说题目中区间修改的问题:因为每一次操作使区间[a,b]的数增加1,区间段中每个数增加了相同的数,那么d[]数组的维护我们可以通过对d[a],d[b+1]的操作实现,即d[a]+=1,d[b+1]-=1(加上/减去改变量)
(支持“先进性区间修改,最后再统一查询”的题目,但边修改边查询的题目只能用其他数据结构)

借助差分数组就将原题的区间修改转化成了单点的修改,最后求每项前缀和的问题,后面的问题就可以用树状数组解决

代码:

#include <iostream>
#include <string.h>
#include<stdio.h>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
#define chl (root<<1)
#define chr ((root<<1)|1)
#define mid ((l+r)>>1)
const LL INF=2e9;
const int manx=1e5+10;
int n,a,b,c[manx];
void add(int x,int val)
{
    if(!x)return;
    while(x<=n)
    {
        c[x]+=val;
        x+=x&(-x);
    }
}
int query(int x)
{
    int ans=0;
    while(x)
    {
        ans+=c[x];
        x-=x&(-x);
    }
    return ans;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,1);
            add(b+1,-1);
        }
        for(int i=1;i<=n;i++)
            printf("%d%c",query(i),i==n?'\n':' ');
    }
}
发布了52 篇原创文章 · 获赞 26 · 访问量 3168

猜你喜欢

转载自blog.csdn.net/qq_43803508/article/details/102532231