• luogu_P3372 【模板】线段树 1


    https://www.luogu.org/problem/P2824

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    输入格式

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入 #1
    5 5
    1 5 4 2 3
    2 2 4
    1 2 3 2
    2 3 4
    1 1 5 1
    2 1 4
    输出 #1
    11
    8
    20

    说明/提示

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^,保证在int64/long long数据范围内)

    样例说明:


    延迟标记:该节点的值已修改,但其左右子节点尚未更新。

    #include<iostream>
    #include<cstdio>
    
    #define ri register int
    #define u long long
    
    namespace opt {
    
        inline u in() {
            u x(0),f(1);
            char s(getchar());
            while(s<'0'||s>'9') {
                if(s=='-') f=-1;
                s=getchar();
            }
            while(s>='0'&&s<='9') {
                x=(x<<1)+(x<<3)+s-'0';
                s=getchar();
            }
            return x*f;
        }
    
    }
    
    using opt::in;
    
    #define NN 100005
    
    namespace xds {
    
        struct node {
            u l,r,sum,add;
        } a[NN<<2];
    
        u b[NN];
    
        void build(const u &rt,const u &l,const u &r) {
            a[rt].l=l,a[rt].r=r;
            if(l==r) {
                a[rt].sum=b[l];
                return;
            }
            u mid(l+r>>1),_x(rt<<1),_y(rt<<1|1);
            build(_x,l,mid);
            build(_y,mid+1,r);
            a[rt].sum=a[_x].sum+a[_y].sum;
        }
    
        void pushdown(const u &rt) {
            if(a[rt].add) {
                u _x(rt<<1),_y(rt<<1|1);
                a[_x].sum+=(a[_x].r-a[_x].l+1)*a[rt].add;
                a[_y].sum+=(a[_y].r-a[_y].l+1)*a[rt].add;
                a[_x].add+=a[rt].add,a[_y].add+=a[rt].add;
                a[rt].add=0;
            }
        }
    
        void update(const u &rt,const u &l,const u &r,const u &x) {
            if(a[rt].l>=l&&a[rt].r<=r) {
                a[rt].sum+=(a[rt].r-a[rt].l+1)*x;
                a[rt].add+=x;
                return;
            }
            pushdown(rt);
            u _x(rt<<1),_y(rt<<1|1);
            if(l<=a[_x].r) update(_x,l,r,x);
            if(r>=a[_y].l) update(_y,l,r,x);
            a[rt].sum=a[_x].sum+a[_y].sum;
        }
    
        u query(const u &rt,const u &l,const u &r) {
            if(a[rt].l>=l&&a[rt].r<=r) return a[rt].sum;
            pushdown(rt);
            u _x(rt<<1),_y(rt<<1|1),_re(0);
            if(l<=a[_x].r) _re+=query(_x,l,r);
            if(r>=a[_y].l) _re+=query(_y,l,r);
            return _re;
        }
    
    }
    
    namespace mainstay {
    
        inline void solve() {
            u N(in()),M(in());
            for(ri i(1); i<=N; ++i) xds::b[i]=in();
            xds::build(1,1,N);
            for(ri i(1); i<=M; ++i) {
                u k(in());
                if(k==1) {
                    u l(in()),r(in()),_x(in());
                    xds::update(1,l,r,_x);
                } else {
                    u l(in()),r(in());
                    printf("%lld
    ",xds::query(1,l,r));
                }
            }
        }
    
    }
    
    int main() {
    
        //freopen("x.txt","r",stdin);
        std::ios::sync_with_stdio(false);
        mainstay::solve();
    
    }
  • 相关阅读:
    Vivado生成及使用edf文件
    ZYNQ Block Design中总线位宽的截取与合并操作
    Modelsim问题集锦
    Questasim10.6c下载安装教程
    ZYNQ工程PL顶层创建block module报错解决
    Linux自定义应用程序及其菜单图标
    OpenWRT DNS无法解析WAN连接的内网服务器域名
    Wishbone总线从接口转Xilinx MIG (Spartan 6)
    Wishbone总线接口RAM
    Windows系统下将目录挂载为一个磁盘并分配盘符
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11776954.html
Copyright © 2020-2023  润新知