poj3468

繼續用splay刷平衡樹的水題,這題帶了下傳標記,比前幾題上了一個層次,第一提交TLE了,常數優化很神奇:在下傳標記時忽略delt=0的情況就AC了,雖然4.5s有點慢,但還是可以接受的~

program poj3468;
type link=^node; node=record value,delt,sum,size:int64; pre:link; ch:array[0..1] of link; end;
var root:link;
    n,i,q,a,b,c:longint;
    ch:char;
    arr:array[1..100002] of longint;
procedure updata(x:link);
begin
 with x^ do begin
  size:=1; sum:=value;
  if ch[0]<>nil then begin inc(size,ch[0]^.size); inc(sum,ch[0]^.sum); end;
  if ch[1]<>nil then begin inc(size,ch[1]^.size); inc(sum,ch[1]^.sum); end;
  inc(sum,size*delt);
 end;
end;
procedure pushdown(x:link);
begin
 with x^ do begin
  if delt=0 then exit;
  inc(value,delt);
  if ch[0]<>nil then begin inc(ch[0]^.delt,delt); inc(ch[0]^.sum,delt*ch[0]^.size); end;
  if ch[1]<>nil then begin inc(ch[1]^.delt,delt); inc(ch[1]^.sum,delt*ch[1]^.size); end;
  delt:=0;
 end;
end;
procedure rotate(x:link;k:longint);
var f:link;
begin
 f:=x^.pre; pushdown(f); pushdown(x);
 f^.ch[1-k]:=x^.ch[k]; if x^.ch[k]<>nil then x^.ch[k]^.pre:=f;
 x^.pre:=f^.pre; if f^.pre<>nil then if f^.pre^.ch[0]=f then f^.pre^.ch[0]:=x else f^.pre^.ch[1]:=x;
 x^.ch[k]:=f; f^.pre:=x; if f=root then root:=x;
 updata(f); updata(x);
end;
procedure splay(x,goal:link);
var y,z:link;
begin
 while x^.pre<>goal do
       if x^.pre^.pre=goal then
          if x^.pre^.ch[0]=x then rotate(x,1)
          else rotate(x,0)
       else begin
            y:=x^.pre; z:=y^.pre;
            if z^.ch[0]=y then
               if y^.ch[0]=x then begin rotate(y,1); rotate(x,1); end
               else begin rotate(x,0); rotate(x,1); end
            else if y^.ch[1]=x then begin rotate(y,0); rotate(x,0); end
                 else begin rotate(x,1); rotate(x,0); end;
       end;
end;
procedure select(k:longint;goal:link);
var r:link; tmp:longint;
begin
 r:=root;
 while r<>nil do begin
       tmp:=1; if r^.ch[0]<>nil then inc(tmp,r^.ch[0]^.size);
       if k=tmp then break;
       if k<tmp then r:=r^.ch[0]
       else begin
            dec(k,tmp); r:=r^.ch[1];
       end;
 end;
 splay(r,goal);
end;
procedure build(father:link;var r:link;low,high:longint);
var mid:longint;
begin
 if low<=high then begin
    mid:=(low+high)shr 1;
    new(r); with r^ do begin value:=arr[mid]; delt:=0; pre:=father; end;
    build(r,r^.ch[0],low,mid-1);
    build(r,r^.ch[1],mid+1,high);
    updata(r);
 end else r:=nil;
end;
begin
 assign(input,'poj3468.in'); reset(input);
 assign(output,'poj3468.out'); rewrite(output);
  readln(n,q);
  for i:=2 to n+1 do read(arr[i]);readln;
  build(nil,root,1,n+2);
  for i:=1 to q do begin
   read(ch);
   if ch='Q' then begin
      readln(a,b);
      select(a+1-1,nil);
      select(b+1+1,root);
      writeln(root^.ch[1]^.ch[0]^.sum);
   end;
   if ch='C' then begin
      readln(a,b,c);
      select(a+1-1,nil);
      select(b+1+1,root);
      inc(root^.ch[1]^.ch[0]^.delt,c);
      updata(root^.ch[1]^.ch[0]);
      updata(root^.ch[1]);
      updata(root);
   end;
  end;
 close(input); close(output);
end.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章