算法模板——线段树3(区间覆盖值+区间求和)
实现功能——1:区间覆盖值;2:区间求和
相比直接的区间加,这个要注重顺序,因为操作有顺序之分。所以这里面的tag应该有个pushup操作(本程序中的ext)
1 var 2 i,j,k,l,m,n,a1,a2,a3,a4:longint; 3 a,b,d:array[0..100000] of longint; 4 function max(x,y:longint):longint;inline; 5 begin 6 if x>y then max:=x else max:=y; 7 end; 8 function min(x,y:longint):longint;inline; 9 begin 10 if x<y then min:=x else min:=y; 11 end; 12 procedure ext(z,x,y:longint);inline; 13 begin 14 if d[z]=0 then exit; 15 a[z]:=b[z]*(y-x+1); 16 if x<>y then 17 begin 18 b[z*2]:=b[z];d[z*2]:=1; 19 b[z*2+1]:=b[z];d[z*2+1]:=1; 20 end; 21 b[z]:=0;d[z]:=0; 22 end; 23 function op(z,x,y,l,r,p:longint):longint;inline; 24 var a3,a4:longint; 25 begin 26 if l>r then exit(0); 27 if (x=l) and (y=r) then 28 begin 29 if d[z]=1 then a[z]:=b[z]*(r-l+1); 30 d[z]:=1;b[z]:=p; 31 exit(p*(r-l+1)-a[z]); 32 end; 33 ext(z,x,y); 34 a3:=op(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2),p); 35 a4:=op(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r,p); 36 a[z]:=a[z]+a3+a4; 37 exit(a3+a4); 38 end; 39 function cal(z,x,y,l,r:longint):longint;inline; 40 begin 41 if l>r then exit(0); 42 if d[z]=1 then exit(b[z]*(r-l+1)); 43 if (x=l) and (y=r) then exit(a[z]); 44 exit(cal(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2))+cal(z*2+1,(x+y) div 2+1,y,max(l,(x+y) div 2+1),r)); 45 end; 46 procedure built(z,x,y:longint);inline; 47 begin 48 if x=y then 49 read(a[z]) 50 else 51 begin 52 built(z*2,x,(x+y) div 2); 53 built(z*2+1,(x+y) div 2+1,y); 54 a[z]:=a[z*2]+a[z*2+1]; 55 end; 56 b[z]:=0;d[z]:=0; 57 end; 58 begin 59 readln(n,m); 60 built(1,1,n); 61 readln; 62 for i:=1 to m do 63 begin 64 read(j); 65 case j of 66 1:begin 67 readln(a1,a2,a3); 68 op(1,1,n,a1,a2,a3); 69 end; 70 2:begin 71 readln(a1,a2); 72 writeln(cal(1,1,n,a1,a2)); 73 end; 74 else halt; 75 end; 76 end; 77 end. 78