线段树小结

单点增加,区间求和

program ex1;
var
  data:array[0..400000]of int64;
  a:array[0..100000]of int64;
  n,i,m,c,x,y:longint;
procedure build(p,l,r:longint);
var mid:longint;
begin
  if l=r then data[p]:=a[r]
   else if l<r then
   begin
     mid:=(l+r) div 2; build(p*2,l,mid); build(p*2+1,mid+1,r);
     data[p]:=data[p*2]+data[p*2+1];
   end;
end;
procedure add(p,l,r,x,num:longint);
var mid:longint;
begin
  if l=r then inc(data[p],num)
  else
   begin
    mid:=(l+r) div 2;
    if x<=mid then add(p*2,l,mid,x,num);
    if x>mid then add(p*2+1,mid+1,r,x,num);
    data[p]:=data[p*2]+data[p*2+1];
   end;
end;
function query(p,l,r,x,y:longint):int64;
var mid,ans:int64;
begin
  if (x<=l)and(r<=y) then exit(data[p])
  else
    begin
     mid:=(l+r) div 2; ans:=0;
     if x<=mid then inc(ans,query(p*2,l,mid,x,y));
     if y>mid then inc(ans,query(p*2+1,mid+1,r,x,y));
     exit(ans);
    end;
end;
begin
  readln(n);
  for i:=1 to n do readln(a[i]);
  build(1,1,n);
  readln(m);
  for i:=1 to m do
   begin
     readln(c,x,y);
     if c=1 then add(1,1,n,x,y) else writeln(query(1,1,n,x,y));
   end;
end.
View Code

 

区间增加,区间求和

program ex3;
var
  data,datb:array[0..800000]of int64;
  a:array[0..200000]of int64;
  n,i,m,g,x,y,r,j:longint; v:int64;
procedure build(p,l,r:longint);
var mid:longint;
begin        datb[p]:=0;
  if l=r then data[p]:=a[l];
  if l<r then
   begin
     mid:=(l+r) div 2;
     build(p*2,l,mid); build(p*2+1,mid+1,r);
     data[p]:=data[p*2]+data[p*2+1];
   end;
end;
procedure update(p,l,r:longint);
var x,y,mid:longint;
begin
  mid:=(l+r) div 2;x:=p*2;y:=p*2+1;
  inc(data[x],(mid-l+1)*datb[p]);
  inc(data[y],(r-mid)*datb[p]);
  inc(datb[x],datb[p]);inc(datb[y],datb[p]); datb[p]:=0;
end;
procedure change(p,x,y,l,r:longint; num:int64);
var mid:longint;
begin
  if (x<=l)and(r<=y) then
    begin data[p]:=data[p]+(r-l+1)*num; datb[p]:=datb[p]+num; end
   else
     begin
       mid:=(l+r) div 2;   update(p,l,r);
       if x<=mid then change(p*2,x,y,l,mid,num);
       if y>mid then change(p*2+1,x,y,mid+1,r,num);
       data[p]:=data[p*2]+data[p*2+1];
     end;
end;
function query(p,x,y,l,r:longint):int64;
var mid:longint; ans:int64;
begin
  if (x<=l)and(r<=y) then exit(data[p])
  else
    begin
      mid:=(l+r) div 2; update(p,l,r);ans:=0;
      if x<=mid then inc(ans,query(p*2,x,y,l,mid));
      if y>mid then inc(ans,query(p*2+1,x,y,mid+1,r));
      exit(ans);
    end;
end;
begin
  readln(n);
  for i:=1 to n do
    read(a[i]);
  build(1,1,n);
  readln(m);
  for i:=1 to m do
   begin
     read(r,x,y);
     if r=1 then begin read(v);change(1,x,y,1,n,v);  end
      else writeln(query(1,x,y,1,n));  readln;
   end;
end.
View Code

 

转载于:https://www.cnblogs.com/qtyytq/p/4913895.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值