宋壬初吧 关注:25贴子:419
  • 2回复贴,共1

war treap的程序

收藏回复

  • 221.194.73.*
program war;
var i,j,k,l,m,n,p,q,r,t,tt,root,d,x:longint;
left,right,father,sontree:array[0..30000] of longint;
hp:array[0..30000] of longint;
heap:array[0..30000] of real;
c:char;
procedure ro(x:longint);
var g,t:longint;
begin
g:=father[x];
sontree[x]:=sontree[g];
sontree[g]:=sontree[right[g]]+sontree[right[x]]+1;
left[g]:=right[x];
father[right[x]]:=g;
if g=root then
begin
root:=x;father[g]:=x;father[x]:=0;right[x]:=g;
end else
begin
if g=left[father[g]] then left[father[g]]:=x else
right[father[g]]:=x;
father[x]:=father[g];
father[g]:=x;right[x]:=g;
end;
end;
procedure lo(x:longint);
var g,t:longint;
begin
g:=father[x];
sontree[x]:=sontree[g];
sontree[g]:=sontree[left[g]]+sontree[left[x]]+1;
right[g]:=left[x];
father[left[x]]:=g;
if g=root then
begin
root:=x;father[g]:=x;father[x]:=0;left[x]:=g;
end else
begin
if g=left[father[g]] then left[father[g]]:=x else
right[father[g]]:=x;
father[x]:=father[g];
father[g]:=x;left[x]:=g;
end;
end;
procedure ins(x:longint);
var g:longint;
begin
g:=root;
sontree[x]:=1;
while true do
begin
inc(sontree[g]);
if hp[x]<hp[g] then
begin
if left[g]=0 then 
begin
left[g]:=x;father[x]:=g;break;
end else g:=left[g];
end else
begin
if right[g]=0 then
begin
right[g]:=x;father[x]:=g;break;
end else g:=right[g];
end;
end;
heap[x]:=random;
while (x<>root)and(heap[x]<heap[father[x]]) do
if x=left[father[x]] then ro(x) else lo(x);
end;
procedure del(x:longint);
var g,t:longint;
begin
while true do
begin
if left[x]>0 then ro(left[x]) else
if right[x]>0 then lo(right[x]) else
break;
end;
g:=x;
while g<>root do
begin
g:=father[g];dec(sontree[g]);
end;
if x=left[father[x]] then left[father[x]]:=0 else right[father[x]]:=0;
father[x]:=0;
end;
procedure ask(x:longint);
var g,t:longint;
begin
if sontree[root]<x then
begin
writeln(-1);
exit;
end;
x:=sontree[root]-x+1;
//writeln(x);
g:=root;
while x>0 do
begin
if sontree[left[g]]>=x then g:=left[g] else
if sontree[left[g]]=x-1 then
begin
writeln(hp[g]);
exit;
end else 
begin
x:=x-sontree[left[g]]-1;
g:=right[g];
end;
end;
end;
procedure pro_1;
begin
readln(i,d);
dec(hp[i],d);
if sontree[root]>1 then
begin
 del(i);
 if hp[i]>0 then ins(i);
end;
end;
procedure pro_2;
begin
readln(i,d);
inc(hp[i],d);
if sontree[root]>1 then
begin
del(i);ins(i);
end;
end;
procedure pro_3;
begin
readln(k);
ask(k);
end;
procedure debug(x:longint);
begin
if left[x]>0 then debug(left[x]);
writeln(x,':',hp[x],'---',left[x],' ',right[x],' ',father[x],' ',heap[x]:0:3);
if right[x]>0 then debug(right[x]);
end;
begin
 assign(input,'war.in');
 reset(input);
 assign(output,'war.out');
 rewrite(output);
  randomize;
readln(n);
for i:=1 to n do read(hp[i]);readln;
root:=1;sontree[1]:=1;heap[1]:=random;
for i:=2 to n do 
begin
ins(i);
//debug(root);
//for x:=1 to i do writeln(x,':',hp[x],'---',left[x],' ',right[x],' ',father[x],' ',heap[x]:0:3);
//writeln;
end;
readln(m);
for tt:=1 to m do
begin
read©;
if c='A' then pro_1;
if c='C' then pro_2;
if c='Q' then pro_3;
//debug(root);
end;
if hp[root]>0 then writeln(sontree[root]) else writeln(0);
 close(output);
end.


1楼2009-10-05 21:00回复
    • 221.194.73.*
    var i,n,s,m,j,k,l,root:longint;
        ch:char;
        a,t,ls,rs,fa:array[0..100000]of longint;
        h:array[0..100000]of real;
    procedure lo(x:longint);
      var p:longint;
    begin
      p:=fa[x];
      if fa[x]=root then root:=x
        else if p=ls[fa[p]] then ls[fa[p]]:=x else rs[fa[p]]:=x;
      fa[x]:=fa[p];
      fa[p]:=x;
      rs[p]:=ls[x];
      ls[x]:=p;
      fa[rs[p]]:=p;
      t[x]:=t[p];
      t[p]:=t[ls[p]]+t[rs[p]]+1;
    end;
    procedure ro(x:longint);
    var p:longint;
    begin
      p:=fa[x];
      if fa[x]=root then root:=x
        else if p=ls[fa[p]] then ls[fa[p]]:=x else rs[fa[p]]:=x;
      fa[x]:=fa[p];
      fa[p]:=x;
      ls[p]:=rs[x];
      rs[x]:=p;
      fa[ls[p]]:=p;
      t[x]:=t[p];
      t[p]:=t[ls[p]]+t[rs[p]]+1;
    end;
    function ms(x:longint):longint;
    begin
      if h[ls[x]]>h[rs[x]] then exit(rs[x]) else exit(ls[x]);
    end;
    procedure re(x:longint);
    begin
      if x=ls[fa[x]] then ro(x) else lo(x);
    end;
    procedure reallocate(x:longint;y:real);
    begin
      h[x]:=y;
      while (h[x]<h[fa[x]])and(x<>root) do re(x);
      while (h[x]>h[ms(x)]) do re(ms(x));
    end;
    procedure delete(x:longint);
      var k:longint;
    begin
      reallocate(x,2);
      if x=ls[fa[x]] then ls[fa[x]]:=0 else rs[fa[x]]:=0;
      k:=x;
      while k<>root do
        begin
          k:=fa[k];
          dec(t[k]);
        end;
    end;
    procedure insert(x,y:longint);
    begin
      inc(t[y]);
      if a[x]<=a[y] then
        begin
          if ls[y]=0 then
            begin
              t[x]:=1;
              fa[x]:=y;
              ls[y]:=x;
              reallocate(x,random);
              exit;
            end
    


    2楼2009-10-05 21:00
    回复
      • 221.194.73.*

            else insert(x,ls[y]);
          end;
        if a[x]>a[y] then
          begin
            if rs[y]=0 then
              begin
                t[x]:=1;
                fa[x]:=y;
                rs[y]:=x;
                reallocate(x,random);
                exit;
              end
            else insert(x,rs[y]);
          end;
      end;
      function search(x:longint):longint;
        var k,p:longint;
      begin
        k:=x;
        p:=root;
        while k>0 do
          begin
            if k-t[rs[p]]=1 then exit(a[p]);
            if t[rs[p]]<k then
            begin
              dec(k,t[rs[p]]+1);
              p:=ls[p];
            end
            else
            begin
              p:=rs[p];
            end;
          end;
        exit(a[p]);
      end;
      begin
        assign(input,'war.in');
        reset(input);
        assign(output,'war.out');
        rewrite(output);
        randomize;
        readln(n);
        for i:=1 to n do
          read(a[i]);
        h[0]:=10;
        root:=1;
        h[1]:=random;
        t[1]:=1;
        for i:=2 to n do
          insert(i,root);
        readln(m);
        for i:=1 to m do
          begin
            read(ch);
            if ch='Q' then
              begin
                readln(k);
                if k>n then
                begin
                  writeln(-1);
                  continue;
                end;
                writeln(search(k));
              end;
            if ch='A' then
              begin
                readln(k,s);
                a[k]:=a[k]-s;
                delete(k);
                if a[k]>0 then insert(k,root) else dec(n);
              end;
            if ch='C' then
              begin
                readln(k,s);
                a[k]:=a[k]+s;
                delete(k);
                insert(k,root);
              end;
          end;
        writeln(n);
        close(output);
      end.


      3楼2009-10-05 21:00
      回复