hdu1754

此题应该是线段树的水题,但是用splay来做显得更有技术含量啊,第一次提交时居然MLE了,懒得写内存回收,用dispose方法过的,速度还可以接受~


program hdu1754;
type link=^node; node=record size,max,value:longint; pre:link; ch:array[0..1] of link; end;
var root:link;
    n,m,i,a,b:longint;ch:char;
    arr:array[1..200002] of longint;
procedure updata(x:link);
begin with x^ do begin
           size:=1; max:=value;
           if ch[0]<>nil then begin
              inc(size,ch[0]^.size);
              if ch[0]^.max>max then max:=ch[0]^.max;
           end;
           if ch[1]<>nil then begin
              inc(size,ch[1]^.size);
              if ch[1]^.max>max then max:=ch[1]^.max;
           end;
      end;
end;
procedure rotate(x:link;k:longint);
var f:link;
begin f:=x^.pre;
      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 root=f 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 p:link; tmp:longint;
begin
     p:=root;
     while p<>nil do begin
           tmp:=1; if p^.ch[0]<>nil then inc(tmp,p^.ch[0]^.size);
           if k=tmp then break;
           if k<tmp then p:=p^.ch[0]
           else begin
                dec(k,tmp); p:=p^.ch[1];
           end;
     end;
     splay(p,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); r^.value:=arr[mid]; r^.pre:=father;
        build(r,r^.ch[0],low,mid-1);
        build(r,r^.ch[1],mid+1,high);
        updata(r);
     end else r:=nil;
end;
procedure flush(r:link);
begin if r=nil then exit;
      flush(r^.ch[0]);
      flush(r^.ch[1]);
      dispose(r);
      r:=nil;
end;
begin
     assign(input,'hdu1754.in'); reset(input);
     assign(output,'hdu1754.out'); rewrite(output);

 while not eof do begin
     readln(n,m);
     for i:=2 to n+1 do read(arr[i]);readln;
     build(nil,root,1,n+2);
     for i:=1 to m do begin
         read(ch);readln(a,b);
         if ch='Q' then begin
            select(a+1-1,nil);
            select(b+1+1,root);
            writeln(root^.ch[1]^.ch[0]^.max);
         end;
         if ch='U' then begin
            select(a+1,nil);
            root^.value:=b;
            updata(root);
         end;
     end;
     flush(root);
 end;
     close(input);close(output);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值