bzoj 3212 线段树

  裸的线段树

/**************************************************************

    Problem: 3212

    User: BLADEVIL

    Language: Pascal

    Result: Accepted

    Time:100 ms

    Memory:19756 kb

****************************************************************/

 

//By BLADEVIL

type

    rec                 =record

        left, right     :longint;

        sum, lazy       :int64;

    end;

     

var

    n, m                :longint;

    a                   :array[0..100010] of int64;

    t                   :array[0..800010] of rec;

 

procedure swap(var a,b:longint);

var

    c                   :longint;

begin

    c:=a; a:=b; b:=c;

end;

     

procedure build(x,l,r:longint);

var

    mid                 :longint;

begin

    t[x].left:=l; t[x].right:=r;

    if l=r then

    begin

        t[x].sum:=a[l];

        exit;

    end;

    with t[x] do mid:=(l+r)>>1;

    build(2*x,l,mid); build(2*x+1,mid+1,r);

    t[x].sum:=(t[2*x].sum+t[2*x+1].sum);

end;

 

procedure change(x,l,r:longint;y:int64);

var

    mid                 :longint;

begin

        if t[x].lazy<>0 then

    begin

        t[2*x].sum:=t[2*x].sum+t[x].lazy*(t[2*x].right-t[2*x].left+1);

        t[2*x].lazy:=t[2*x].lazy+t[x].lazy;

        t[2*x+1].sum:=t[2*x+1].sum+t[x].lazy*(t[2*x+1].right-t[2*x+1].left+1);

        t[2*x+1].lazy:=t[2*x+1].lazy+t[x].lazy;

        t[x].lazy:=0;

    end;

     

    if (t[x].left=l) and (t[x].right=r) then

    begin

        t[x].lazy:=y;

        t[x].sum:=t[x].sum+y*(t[x].right-t[x].left+1);

        exit;

    end;

    with t[x] do mid:=(left+right)>>1;

    if mid<l then change(2*x+1,l,r,y) else

    if mid>=r then change(2*x,l,r,y) else

    begin

        change(2*x,l,mid,y);

        change(2*x+1,mid+1,r,y);

    end;

    t[x].sum:=t[2*x].sum+t[2*x+1].sum;

end;

 

function ask(x,l,r:longint):int64;

var

    mid                 :longint;

begin

    if t[x].lazy<>0 then

    begin

        t[2*x].sum:=t[2*x].sum+t[x].lazy*(t[2*x].right-t[2*x].left+1);

        t[2*x].lazy:=t[2*x].lazy+t[x].lazy;

        t[2*x+1].sum:=t[2*x+1].sum+t[x].lazy*(t[2*x+1].right-t[2*x+1].left+1);

        t[2*x+1].lazy:=t[2*x+1].lazy+t[x].lazy;

        t[x].lazy:=0;

    end;

     

    if (t[x].left=l) and (t[x].right=r) then exit(t[x].sum);

     

    with t[x] do mid:=(left+right)>>1;

    if mid<l then exit(ask(2*x+1,l,r)) else

    if mid>=r then exit(ask(2*x,l,r)) else

    exit(ask(2*x,l,mid)+ask(2*x+1,mid+1,r));

end;

 

procedure init;

var

    i                   :longint;

begin

    readln(n,m);

    for i:=1 to n do read(a[i]);

    readln;

    build(1,1,n);

end;

 

procedure main;

var

    i                   :longint;

    ch                  :char;

    l, r                :longint;

    x                   :int64;

begin

    for i:=1 to m do

    begin

        read(ch);

        if ch='C' then

        begin

            readln(l,r,x);

            if l>r then swap(l,r);

            change(1,l,r,x);

        end else

        begin

            readln(l,r);

            if l>r then swap(l,r);

            writeln(ask(1,l,r));

        end;

    end;

end;

 

begin

    init;

    main;

end.

 

你可能感兴趣的:(线段树)