luogu 3372模板线段树1

Posted Emine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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 }

以上是关于luogu 3372模板线段树1的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P3372 模板线段树 1

luogu P3372 线段树1模板

线段树lazy模板 luogu3372

luogu_3372 模板线段树 1

洛谷P3372线段树模板1——线段树

luogu P3372ybtoj线段树课堂过关例题2区间查改 &模板线段树 1