[NOI2003]文本编辑器

Splay裸题。考前提升下代码能力。速度进了Tyvj的Rank5……

测试数据 #1: Accepted, time=374ms, mem=37870KB, score=10
测试数据 #2: Accepted, time=0ms, mem=37874KB, score=10
测试数据 #3: Accepted, time=46ms, mem=37870KB, score=10
测试数据 #4: Accepted, time=109ms, mem=37870KB, score=10
测试数据 #5: Accepted, time=109ms, mem=37874KB, score=10
测试数据 #6: Accepted, time=46ms, mem=37866KB, score=10
测试数据 #7: Accepted, time=62ms, mem=37870KB, score=10
测试数据 #8: Accepted, time=62ms, mem=37870KB, score=10
测试数据 #9: Accepted, time=202ms, mem=37870KB, score=10
测试数据 #10: Accepted, time=327ms, mem=37870KB, score=10
Time = 1337ms Mem = 37874KB Score= 100

program editor;


Type
 rec=record
  l,r,fa,s:longint;
  w:char;
 end;

Var
 n,m,i,h,now,len,top,u,t:longint;
 c:char;
 ss:array[0..1800000] of char;
 f:array[0..1800000] of rec;

Procedure readchar(P:longint);inline;
var
 c:char;
  begin
  while p>0 do begin read(c);dec(p); end;
end;

Procedure update(P:longint);inline;
  begin
  if p=0 then exit;
  f[p].s:=f[f[p].l].s+f[f[p].r].s+1;
end;

Procedure zig(P:longint);inline;
var
 u:longint;
  begin
  u:=f[p].r;
  if u=0 then exit;//重要!
  f[p].r:=f[u].l;
  if f[p].r<>0 then f[f[p].r].fa:=p;
  f[u].fa:=f[p].fa;
  if f[p].fa<>0 then if f[f[p].fa].l=p then f[f[p].fa].l:=u else f[f[p].fa].r:=u else h:=u;
  f[u].l:=p;
  f[p].fa:=u;
  update(p);update(u);
end;

Procedure zag(P:longint);inline;
var
 u:longint;
  begin
  u:=f[p].l;
  if u=0 then exit;
  f[p].l:=f[u].r;
  if f[p].l<>0 then f[f[p].l].fa:=p;
  f[u].fa:=f[p].fa;
  if f[p].fa<>0 then if f[f[p].fa].l=p then f[f[p].fa].l:=u else f[f[p].fa].r:=u else h:=u;
  f[u].r:=p;
  f[p].fa:=u;
  update(p);
  update(u);
end;

Procedure up(x,root:longint);inline;
  begin
  if f[root].l=x then zag(root) else zig(root);
end;

Procedure splay(P,tar:longint);inline;
var
 x,y,z:longint;
  begin
  x:=p;y:=f[x].fa;z:=f[y].fa;
  while y<>tar do
    begin
    if z=tar then begin up(x,y);break; end;
    if ((f[z].l=y) xor (f[y].l=x))=false then
      begin
      up(y,z);
      up(x,y);
    end else
      begin
      up(x,y);
      up(y,z);
    end;
    y:=f[x].fa;
    z:=f[y].fa;
  end;
end;

Function Fnext:longint;inline;
var
 x,y:longint;
  begin
  if f[now].r<>0 then
    begin
    fnext:=f[now].r;
    while f[fnext].l<>0 do fnext:=f[fnext].l;
    exit(fnext);
  end;
  x:=now;
  y:=f[now].fa;
  while f[y].r=x do begin y:=f[y].fa;x:=f[x].fa; end;
  exit(y);
  splay(now,0);
end;

Procedure next;inline;
  begin
  now:=fnext;
end;

Procedure prev;inline;
var
 x,y:longint;
  begin
  if f[now].l<>0 then
    begin
    now:=f[now].l;
    while f[now].r<>0 do now:=f[now].r;
    exit;
  end;
  x:=now;
  y:=f[x].fa;
  while f[y].l=x do begin y:=f[y].fa;x:=f[x].fa; end;
  now:=y;
  splay(now,0);
end;

Function index(P,num:longint):longint;
  begin
  while true do begin
  if f[f[p].l].s+1=num then exit(p);
  if f[f[p].l].s+1<num then
    begin
    dec(num,f[f[p].l].s+1);
    p:=f[p].r;
  end
  else
    p:=f[p].l;
  end;
end;

Procedure move(P:longint); inline;
  begin
  now:=index(h,p+1);
end;

Procedure print(P:longint);
  begin
  if f[p].l>0 then print(f[p].l);
  {if (f[p].w>#31) and (f[p].w<#127) then} write(f[p].w);
  if f[p].r>0 then print(f[p].r);
end;

Procedure get(P:longint); inline;
var
 x:longint;
  begin
  splay(now,0);  x:=index(h,f[f[now].l].s+2+p);
  splay(x,now);
  print(f[x].l);
end;

Procedure Delete(P:longint); inline;
var
 x:longint;
  begin
  splay(now,0);  x:=index(h,f[f[now].l].s+2+p);
  splay(x,now);
  f[x].l:=0;
  while x<>0 do
    begin
    dec(f[x].s,p);
    x:=f[x].fa;
  end;
end;

Function add(pfa:longint):longint; inline;
  begin
  inc(top);
  f[top].fa:=pfa;
  exit(top);
end;

Procedure build(p,l,r:longint);
var
 mid:longint;
  begin
  mid:=(l+r) div 2;
  f[p].w:=ss[mid];
  f[p].s:=r-l+1;
  if l=r then exit;
  if mid>l then begin f[p].l:=add(p);
  build(f[p].l,l,mid-1); end;
  if mid<r then begin f[p].r:=add(p);
  build(f[p].r,mid+1,r); end;
end;

Procedure insert;
var
 u:longint;
  begin
  splay(now,0);
  u:=fnext;
  f[u].l:=add(u);
  build(f[u].l,1,len);
  while u>0 do
    begin
    inc(f[u].s,len);
    u:=f[u].fa;
  end;
end;

  begin
  
  with f[1] do
    begin
    s:=2;
    w:=#1;
    r:=2;
  end;
  with f[2] do
    begin
    s:=1;
    w:=#255;
    fa:=1;
  end;
  top:=2;
  now:=1; h:=1;
  readln(t);
  while t>0 do
    begin
    dec(t);
    read(c);
    case c of
      'M':
        begin
        readchar(3);
        readln(u);
        move(u);
      end;
      'I':
        begin
        readchar(5);
        readln(len);
        for i:=1 to len do
          begin
          read(ss[i]);
          while eoln do readln;
        end;
        insert;
      end;
      'N':
        begin
        readchar(3);
        readln;
        next;
      end;
      'P':
        begin
        readchar(3);
        readln;
        prev;
      end;
      'D':
        begin
        readchar(5);
        readln(u);
        delete(u);
      end;
      'G':
        begin
        readchar(3);
        readln(u);
        get(u);
        writeln;
      end;
    end;

  end;

end.
原文地址:https://www.cnblogs.com/htfy/p/3069986.html