线段树(codevs1082)

type jd=record
  z,y,lc,rc,sum,toadd:int64;
    end;

var
 tree:array[0..800000] of jd;   
 qzh:array[0..200000] of int64;
 x:array[1..200000] of int64;
 n,m,a,b,k,ans,tot,t:int64;
 i,j:longint;

 function min(a,b:longint):longint;
   begin
     if a<b then exit(a) else exit(b);
   end;

 function max(a,b:longint):longint;
   begin
     if a>b then exit(a) else exit(b);
   end;

 procedure maketree(a,b:longint);
 var
  mid,t:longint;
    begin
      inc(tot);
      t:=tot;
      tree[t].z:=a;tree[t].y:=b;
      tree[t].sum:=qzh[b]-qzh[a-1];
      mid:=(a+b) div 2;
      if a<b then
        begin
          tree[t].lc:=tot+1;
          maketree(a,mid);
          tree[t].rc:=tot+1;
          maketree(mid+1,b);
        end;
    end;

 procedure add(po,a,b,k:longint);
 var
  mid:longint;
    begin
      mid:=(tree[po].z+tree[po].y) div 2;

      tree[po].sum:=tree[po].sum+k*(min(b,tree[po].y)-max(a,tree[po].z)+1)+tree[po].toadd*(tree[po].y-tree[po].z+1);

        if tree[po].toadd<>0 then
        begin
          tree[tree[po].lc].toadd:=tree[tree[po].lc].toadd+tree[po].toadd;
          tree[tree[po].rc].toadd:=tree[tree[po].rc].toadd+tree[po].toadd;
          tree[po].toadd:=0;
        end;

      if (a=tree[po].z)and(b=tree[po].y) then
        begin
          tree[tree[po].lc].toadd:=tree[tree[po].lc].toadd+k;
          tree[tree[po].rc].toadd:=tree[tree[po].rc].toadd+k;
        end else
         begin
           if a<=mid then add(tree[po].lc,a,min(b,mid),k);
           if b>mid then add(tree[po].rc,max(a,mid+1),b,k);
         end;
    end;

  procedure getans(po,a,b:longint);
  var
   mid:longint;
    begin
      if tree[po].toadd<>0 then
        begin
          tree[po].sum:=tree[po].sum+tree[po].toadd*(tree[po].y-tree[po].z+1);
          tree[tree[po].lc].toadd:=tree[tree[po].lc].toadd+tree[po].toadd;
          tree[tree[po].rc].toadd:=tree[tree[po].rc].toadd+tree[po].toadd;
          tree[po].toadd:=0;
        end;

      mid:=(tree[po].z+tree[po].y) div 2;
      if (a=tree[po].z) and (b=tree[po].y) then
        ans:=ans+tree[po].sum else
          begin
            if a<=mid then getans(tree[po].lc,a,min(b,mid));
            if b>mid then getans(tree[po].rc,max(a,mid+1),b);
          end;
    end;

  begin

    readln(n);
    for i:=1 to n do
      begin
        read(x[i]);
        qzh[i]:=qzh[i-1]+x[i];
      end;

    maketree(1,n);

    read(m);
    for i:=1 to m do
      begin
        read(t);
        if t=1 then
          begin
            read(a,b,k);
            add(1,a,b,k);
          end;
        if t=2 then
          begin
            read(a,b);
            ans:=0;
            getans(1,a,b);
            writeln(ans);
          end;
      end;

  end.
原文地址:https://www.cnblogs.com/zhujiangning/p/5212984.html