zoukankan      html  css  js  c++  java
  • poj-3468 A Simple Problem with Integers

    线段树的模板题!区间更新

    区间更新的关键在于lazy标记,

    如果要更新的区间包括当前的区间的话,就加对当前的这个区间加一个lazy标记,更新整个区间的值,并且停止,不再继续往下更新,

    当再次更新到这个区间的时候,就是会用到这个这个区间的值的时候,

    就把这个lazy标记释放掉(更新左子树和右子树,同时消除lazy标记)

    这个题对区间的更新是同时对每个数字加上或减去同一个数字(c)

    如果当前区间的左右端点分别是ls,rs的话,更新的话就是+(-)(rs-ls+1)*c;

    # include <cstdio>
    # include <iostream>
    # include <cstring>
    # include <algorithm>
    using namespace std;
    
    const int maxn=1e5+5;
    long long int sum[maxn*4],seg[maxn*4];
    
    void pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    
    void pushdown(int l,int r,int rt){
        int mid=(l+r)>>1;
            seg[rt<<1]+=seg[rt];
            sum[rt<<1]+=(mid-l+1)*seg[rt];
            seg[rt<<1|1]+=seg[rt];
            sum[rt<<1|1]+=(r-mid)*seg[rt];
            seg[rt]=0;
    }
    
    void build(int l,int r,int rt){
        seg[rt]=0;
        if(l==r) {
            scanf("%lld",&sum[rt]);
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        pushup(rt);
    }
    
    void update(int L,long long int R,int l,int r,int rt,int c){
        if(L<=l&&r<=R) {
            seg[rt]+=c;
            sum[rt]+=(r-l+1)*c;
            return ;
        }
        if(seg[rt]) pushdown(l,r,rt);
        int mid=(l+r)>>1;
        if(L<=mid) update(L,R,l,mid,rt<<1,c);
        if(mid<R) update(L,R,mid+1,r,rt<<1|1,c);
        pushup(rt);
    }
    
    long long int query(int L,int R,int l,int r,int rt){
        if(L<=l&&r<=R){
            return sum[rt];
        }
        if(seg[rt]) pushdown(l,r,rt);
        int mid=(l+r)>>1;
        long long int ans=0;
        if(L<=mid) ans+=query(L,R,l,mid,rt<<1);
        if(mid<R) ans+=query(L,R,mid+1,r,rt<<1|1);
        pushup(rt);
        return ans;
    }
    
    int main(){
        long long int n,q;
        while(scanf("%lld%lld",&n,&q)==2&&n&&q){
            build(1,n,1);
            char s[5];
            long long int a,b;
            int c;
            for(long long int i=0;i<q;i++){
                scanf("%s",s);
                if(s[0]=='Q'){
                    scanf("%lld%lld",&a,&b);
                    printf("%lld
    ",query(a,b,1,n,1));
                }
                if(s[0]=='C'){
                    scanf("%lld%lld%d",&a,&b,&c);
                    update(a,b,1,n,1,c);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    1.IntelliJ IDEA搭建SpringBoot的小Demo
    etc目录名字的意思---挖Linux中的古老缩略语
    CI当开启URL重写的时候,报错500 Internal Server Error
    app后端架构设计(转)
    Redis安装及主从配置
    ***Linux文件夹文件创建、删除、改名
    Redis中常用命令
    linux上ln链接命令详细说明
    Redis快速入门:安装、配置和操作
    redis的PHP扩展包安装方法
  • 原文地址:https://www.cnblogs.com/lintanxi/p/6786506.html
Copyright © 2011-2022 走看看