计蒜客木桩涂涂看

版权声明:原创博客 喜欢拿走 https://blog.csdn.net/qq_43004519/article/details/85159354

题目

个木桩排成一排,从左到右依次编号为 1,2,3…n1,2,3…n。每次给定 22 个整数 a,b(a≤b),蒜头君便骑上他的电动车从木桩 a 开始到木桩 b 依次给每个木桩涂一次颜色。但是 n 次以后 lele 已经忘记了第 i 个木桩已经涂过几次颜色了,你能帮他算出每个木桩被涂过几次颜色吗?

输入格式
第一行是一个整数 n(n≤100000)。

接下来的 n 行,每行包括两个整数 a, b (1≤a≤b≤n)。

输出格式
n 个整数,第 ii 个数代表第 i 个木桩总共被涂色的次数。

分析

以木桩建立树状数组,之前我们做的树状数组都是单点更新,并没有区间更新,那现在变换一下思路,以树状数组的前n项和再建立一个数组。
假设有8个木桩,输入2,6
change(a,1);
change(b+1,-1);

	下标                 	      1	2	3	4	5	6	7	8
树状数组c[8]			      0	1	0	1	0	0	0	1
树状数组前n项和 sum[8]        0	1	1	1	1	1	0	0

注意观察sum数组的值,就可以明白树状数组的区间更新

AC

#include<iostream>/*树状数组的区间更新*/
using namespace std;

const int MAXN=1e5+1;
int tree[MAXN];
int n,a,b;

void change(int x,int v){
    for(;x<=n;x+=x&(-x))
        tree[x]+=v;
    return;
}
int getsum(int x){
    int re=0;
    for(;x;x-=x&(-x))
        re+=tree[x];
    return re;
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a>>b;
        change(a,1);//在getsum(i)构成的数组中就是从a开始都变为1
        change(b+1,-1);//在getsum(i)构成的数组中就从b开始(因为b>a),因此从b开始都为0,而0到a也为0,只有a到b都是1,这就实现了区间更新
    }
    for(int i=1;i<=n;i++){
        if(i==1)
            cout<<getsum(i);
        else
            cout<<" "<<getsum(i);
    }
    return 0;//give me five
}

猜你喜欢

转载自blog.csdn.net/qq_43004519/article/details/85159354