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.

 

posted on 2014-01-15 19:16  BLADEVIL  阅读(348)  评论(0编辑  收藏  举报