• 【luogu 3372】【模板】线段树1


    题目描述

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

    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数据范围内)

    样例说明:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll l,mid,rt<<1
     6 #define rr mid+1,r,rt<<1|1
     7 #define LL long long
     8 #define maxn 100005
     9 using namespace std;
    10 LL add[maxn<<2],sum[maxn<<2];
    11 void pushdown(int rt,int m){
    12     if(add[rt]){
    13         add[rt<<1]+=add[rt];
    14         add[rt<<1|1]+=add[rt];
    15         sum[rt<<1]+=add[rt]*(m-(m>>1));
    16         sum[rt<<1|1]+=add[rt]*(m>>1);
    17         add[rt]=0;
    18     }
    19 }
    20 void build(int l,int r,int rt){
    21     add[rt]=0;
    22     if(l==r){
    23         scanf("%lld",&sum[rt]);
    24         return ;
    25     }
    26     int mid=(l+r)>>1;
    27     build(ll);build(rr);
    28     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    29 }
    30 void update(int ql,int qr,int c,int l,int r,int rt){
    31     if(ql<=l&&r<=qr){
    32         add[rt]+=c;
    33         sum[rt]+=(LL)c*(r-l+1);
    34         return ;
    35     }
    36     pushdown(rt,r-l+1);
    37     int mid=(l+r)>>1;
    38     if(ql<=mid) update(ql,qr,c,ll);
    39     if(mid<qr) update(ql,qr,c,rr);
    40     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    41 }
    42 LL query(int ql,int qr,int l,int r,int rt){
    43     if(ql<=l&&r<=qr) return sum[rt];
    44     pushdown(rt,r-l+1);
    45     int mid=(l+r)>>1;
    46     LL ret=0;
    47     if(ql<=mid) ret+=query(ql,qr,ll);
    48     if(mid<qr) ret+=query(ql,qr,rr);
    49     return ret;
    50 }
    51 int main(){
    52     int n,q;
    53     scanf("%d%d",&n,&q);
    54     build(1,n,1);
    55     while(q--){
    56         int Q;
    57         int a,b,c;
    58         scanf("%d",&Q);
    59         if(Q==2){
    60             scanf("%d%d",&a,&b);
    61             printf("%lld
    ",query(a,b,1,n,1));
    62         }
    63         else{
    64             scanf("%d%d%d",&a,&b,&c);
    65             update(a,b,c,1,n,1);
    66         }
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    [转] linux虚拟带库操作笔记
    [转] 在Linux平台使用mhVTL虚拟化磁带库
    [转] mhvtl虚拟磁带库的安装与应用
    RHEL 集群(RHCS)配置小记 -- 文档记录
    Oracle Database常用补丁集Patch号及各版本PSU
    [原创] ORA-01536 超出表空间 'xxxx' 的空间限额
    div里面的图片超出div的宽度,自动调整大小。
    SDNU 1269.整数序列(水题)
    SDNU 1254.Problem B. SOS(水题)
    SDNU 1245.这题超难的,建议先做其他的,看都不要看(思维)
  • 原文地址:https://www.cnblogs.com/Emine/p/7668751.html
Copyright © 2020-2023  润新知