hdu1556 Color the ball 线段树基础题 区间更新 单点查询 懒惰标记

版权声明:点个关注(^-^)V https://blog.csdn.net/weixin_41793113/article/details/89889529

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

 

Problem Description

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

Input

每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
当N = 0,输入结束。

Output

每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。

Sample Input

3

1 1

2 2

3 3

3

1 1

1 2

1 3

0

Sample Output

1 1 1

3 2 1

Source

HDU 2006-12 Programming Contest

向上更新,这个比较简单,维护线段树基本操作

void pushup(int u){
    tree[u].sum = tree[2*u].sum + tree[2*u+1].sum;
}

向下更新,懒惰标记的核心维护代码

void pushdown(int u){
    if(tree[u].lazy!=0){
        tree[2*u].sum+=tree[u].lazy;
        tree[2*u+1].sum+=tree[u].lazy;
        tree[2*u].lazy+=tree[u].lazy;
        tree[2*u+1].lazy+=tree[u].lazy;
        tree[u].lazy=0;//置0
    }
}

区间更新 单点查询 懒惰标记 模板模板模板,背背背记记记,练练练

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

typedef long long ll;
const int MAX = 1e5+5;

struct {
    int l,r;
    ll sum,lazy;
}tree[4*MAX+5];

int n,a,b;

void pushup(int u){
    tree[u].sum = tree[2*u].sum + tree[2*u+1].sum;
}

void pushdown(int u){
    if(tree[u].lazy!=0){
        tree[2*u].sum+=tree[u].lazy;
        tree[2*u+1].sum+=tree[u].lazy;
        tree[2*u].lazy+=tree[u].lazy;
        tree[2*u+1].lazy+=tree[u].lazy;
        tree[u].lazy=0;//置0
    }
}

void buildTree(int u,int l,int r){
    tree[u].sum=tree[u].lazy=0;
    tree[u].l = l;
    tree[u].r = r;
    if(l==r)
        return;

    int mid = l+(r-l)/2;
    buildTree(2*u,l,mid);
    buildTree(2*u+1,mid+1,r);
}

void update(int u,int x,int y,int add){
    if(tree[u].l>=x && tree[u].r<=y){//这边界不要写偏
        tree[u].sum+=add;
        tree[u].lazy+=add;
        return;
    }
    pushdown(u);
    int mid = tree[u].l + (tree[u].r-tree[u].l)/2;
    if(x<=mid)
        update(2*u,x,y,add);
    if(y>mid)
        update(2*u+1,x,y,add);
    pushup(u);
}

ll query(int u,int x,int y){
    if(tree[u].l>=x && tree[u].r<=y){
        return tree[u].sum;
    }
    pushdown(u);
    ll ans=0;
    int mid = tree[u].l + (tree[u].r-tree[u].l)/2;
    if(x<=mid)
        ans+=query(2*u,x,y);
    if(y>mid)
        ans+=query(2*u+1,x,y);

    return ans;
}

int main(){

    while(~scanf("%d",&n),n){
        buildTree(1,1,n);

        for(int i=1;i<=n;i++){
            scanf("%d%d",&a,&b);
            update(1,a,b,1);
        }

        for(int i=1;i<=n;i++)
            if(i!=n)
                printf("%lld ",query(1,i,i));
            else
                printf("%lld\n",query(1,i,i));

    }

	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41793113/article/details/89889529
今日推荐