洛谷 p3372 模板-线段树 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数据范围内)
样例说明:
线段树模版题qwq ,lazytag终于搞懂啦!
1 program gai; 2 const 3 inf='gai.in'; 4 outf='gai.out'; 5 type 6 arr=array[1..100000] of longint; 7 tree=^nod; 8 nod=record 9 lc,rc:tree; 10 l,r,val,lazy:int64; 11 end; 12 var 13 i,m,n,x,y,k:longint; 14 a:arr; 15 t:tree; 16 17 procedure build(var t:tree; l,r:longint; var a:arr); 18 var 19 mid:int64; 20 begin 21 new(t); t^.l:=l; t^.r:=r; t^.lazy:=0; 22 if l=r then begin 23 t^.val:=a[l]; 24 exit; 25 end; 26 mid:=(l+r) div 2; 27 build(t^.lc,l,mid,a); 28 build(t^.rc,mid+1,r,a); 29 t^.val:=t^.lc^.val+t^.rc^.val; 30 end; 31 32 procedure clean(var t:tree); 33 begin 34 if t^.lazy=0 then exit; 35 if t^.lc<>nil then 36 begin 37 t^.lc^.val:=t^.lc^.val+t^.lazy*(t^.lc^.r-t^.lc^.l+1); 38 t^.lc^.lazy:=t^.lc^.lazy+t^.lazy; 39 end; 40 if t^.rc<>nil then 41 begin 42 t^.rc^.val:=t^.rc^.val+t^.lazy*(t^.rc^.r-t^.rc^.l+1); 43 t^.rc^.lazy:=t^.rc^.lazy+t^.lazy; 44 end; 45 t^.lazy:=0; 46 end; 47 48 procedure add(var t:tree; x,y:longint; v:longint); 49 begin 50 if (x<=t^.l) and (t^.r<=y) then begin 51 t^.val:=t^.val+(t^.r-t^.l+1)*v; 52 t^.lazy:=t^.lazy+v; 53 exit; 54 end; 55 clean(t); 56 if x<=t^.lc^.r then add(t^.lc,x,y,v); 57 if t^.rc^.l<=y then add(t^.rc,x,y,v); 58 t^.val:=t^.lc^.val+t^.rc^.val;///////////////lazy??? 59 end; 60 61 function query(var t:tree; x,y:longint):int64; 62 begin 63 query:=0; 64 if (x<=t^.l) and (t^.r<=y) then exit(t^.val); 65 clean(t); 66 if x<=t^.lc^.r then query:=query+query(t^.lc,x,y); 67 if t^.rc^.l<=y then query:=query+query(t^.rc,x,y); 68 end; 69 70 begin 71 72 //assign(input,inf); assign(output,outf); 73 reset(input); rewrite(output); 74 75 readln(n,m); 76 for i:= 1 to n do 77 read(a[i]); 78 79 build(t,1,n,a); 80 81 for i:= 1 to m do 82 begin 83 read(k,x,y); 84 if k=1 then begin 85 86 read(k); 87 add(t,x,y,k); 88 end 89 else writeln(query(t,x,y)); 90 end; 91 92 close(input); close(output); 93 end.