KWY的splay总结

转自小天才 KWY


3223

裸的区间反转,注意在最左边和最右边加上俩点


3224

各种平衡树都可以写,全是最裸的操作练习


1861

因为这道题结点的总数始终不会改变,改变的只是顺序,所以可以在插入结点时记录下当前编号的书在树中的结点下标,修改的时候先靠记录下来的下标找到然后转到顶删掉,再转出来要插入的位置,把删掉的这个节点挂上去,注意,这里插入结点时不能开新结点,而是把删掉的那个结点的爹还有它爸爸的儿子改一下接着用


1507

这个是LDNPGBD块状链表的练习题,但显然splay简单得多...

这道题告诉我们,千万不要用PASCAL的傻逼ansistring啊啊啊啊啊!!!

用ansistring本地测6s+ BZOJ直接TLE... 害得我把能优化的都优化了一遍还是TLE...

Hydra:换字符数组吧    似乎有点道理...试试...然后本地0.9s交上去直接就A了...TAT

然后我又把优化都去掉试了试,发现7行splay和40行splay效率只差0.3s...差不多嘛...



 1012

这是个线段树...但是splay可以水过...


1056&1862

这题有组数据专卡splay,似乎能卡100s+...这道题总共2TLE+9RE...真是够了...无奈写了个SBT,还挺快


代码:

program bzoj_3224;
type rec=record lc,rc,key,size:longint; end;
var s:array[0..100000]of rec;
    root,q,cas,m,tot:longint;

procedure l_rotate(var t:longint);
var k:longint;
begin
  k:=s[t].rc;
  s[t].rc:=s[k].lc;
  s[k].lc:=t;
  s[k].size:=s[t].size;
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  t:=k;
end;

procedure r_rotate(var t:longint);
var k:longint;
begin
  k:=s[t].lc;
  s[t].lc:=s[k].rc;
  s[k].rc:=t;
  s[k].size:=s[t].size;
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  t:=k;
end;

procedure maintain(var t:longint;flag:boolean);
begin
  if not flag then
  if s[s[s[t].lc].lc].size>s[s[t].rc].size then r_rotate(t) else
  if s[s[s[t].lc].rc].size>s[s[t].rc].size then
  begin
    l_rotate(s[t].lc);
    r_rotate(t);
  end else exit;
  if flag then
  if s[s[s[t].rc].rc].size>s[s[t].lc].size then l_rotate(t) else
  if s[s[s[t].rc].lc].size>s[s[t].lc].size then
  begin
    r_rotate(s[t].rc);
    l_rotate(t);
  end else exit;
  maintain(s[t].lc,false);
  maintain(s[t].rc,true);
  maintain(t,false);
  maintain(t,true);
end;

procedure insert(var t,x:longint);
begin
  if t=0 then
  begin
    inc(tot);
    t:=tot;
    s[t].lc:=0;
    s[t].rc:=0;
    s[t].size:=1;
    s[t].key:=x;
  end else
  begin
    inc(s[t].size);
    if x<s[t].key then
    begin
      insert(s[t].lc,x);
      maintain(t,false);
    end else
    begin
      insert(s[t].rc,x);
      maintain(t,true);
    end;
  end;
end;

function delete(var t:longint;x:longint):longint;
begin
  dec(s[t].size);
  if (s[t].key=x)or((x<s[t].key)and(s[t].lc=0)or(x>s[t].key)and(s[t].rc=0)) then
  begin
    delete:=s[t].key;
    if (s[t].lc=0)or(s[t].rc=0) then t:=s[t].lc+s[t].rc
    else s[t].key:=delete(s[t].lc,s[t].key+1);
  end else
  if x<s[t].key then exit(delete(s[t].lc,x)) else exit(delete(s[t].rc,x));
end;

function rank(var t,x:longint):longint;
begin
  if t=0 then exit(1);
  if x<=s[t].key then exit(rank(s[t].lc,x)) else exit(rank(s[t].rc,x)+s[s[t].lc].size+1);
end;

function find(var t:longint;x:longint):longint;
begin
  if x=s[s[t].lc].size+1 then exit(s[t].key);
  if x<=s[s[t].lc].size then exit(find(s[t].lc,x)) else exit(find(s[t].rc,x-1-s[s[t].lc].size));
end;

function pred(var t,x:longint):longint;
begin
  if t=0 then exit(x);
  if x<=s[t].key then exit(pred(s[t].lc,x)) else
  begin
    pred:=pred(s[t].rc,x);
    if pred=x then exit(s[t].key);
  end;
end;

function succ(var t,x:longint):longint;
begin
  if t=0 then exit(x);
  if s[t].key<=x then exit(succ(s[t].rc,x)) else
  begin
    succ:=succ(s[t].lc,x);
    if succ=x then exit(s[t].key);
  end;
end;

begin
  readln(q);
  root:=0;
  tot:=0;
  for q:=1 to q do
  begin
    readln(cas,m);
    case cas of
      1:insert(root,m);
      2:delete(root,m);
      3:writeln(rank(root,m));
      4:writeln(find(root,m));
      5:writeln(pred(root,m));
      6:writeln(succ(root,m));
    end;
  end;
end.

//=================================

program bzoj_3223;
var s:array[0..100002]of record lc,rc,fa,size,key:longint; rev:boolean; end;
    root,tot,n,m,l,r:longint;

procedure l_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].rc:=s[t].lc;
  if s[t].lc<>0 then s[s[t].lc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].size:=s[p].size;
  s[p].size:=s[s[p].lc].size+s[s[p].rc].size+1;
  s[p].fa:=t;
  s[t].lc:=p;
end;

procedure r_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].lc:=s[t].rc;
  if s[t].rc<>0 then s[s[t].rc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].size:=s[p].size;
  s[p].size:=s[s[p].lc].size+s[s[p].rc].size+1;
  s[p].fa:=t;
  s[t].rc:=p;
end;

procedure splay(t:longint);
begin
  while s[t].fa<>0 do
  if t=s[s[t].fa].lc then r_rotate(t) else l_rotate(t);
  root:=t;
end;

procedure insert(x:longint);
var p,pre:longint;
begin
  p:=root;
  pre:=root;
  while p<>0 do
  begin
    pre:=p;
    inc(s[p].size);
    if x<s[p].key then p:=s[p].lc else p:=s[p].rc;
  end;
  inc(tot);
  s[tot].fa:=pre;
  s[tot].lc:=0;
  s[tot].rc:=0;
  s[tot].key:=x;
  s[tot].size:=1;
  s[tot].rev:=false;
  if pre<>0 then if x<s[pre].key then s[pre].lc:=tot else s[pre].rc:=tot;
  splay(tot);
end;

procedure update(t:longint);
var p:longint;
begin
  p:=s[t].lc;
  s[t].lc:=s[t].rc;
  s[t].rc:=p;
  s[s[t].lc].rev:=not s[s[t].lc].rev;
  s[s[t].rc].rev:=not s[s[t].rc].rev;
  s[t].rev:=not s[t].rev;
end;

procedure find(x:longint);
var p:longint;
begin
  if (x<>1)and(x<>n+2) then
  begin
    p:=root;
    repeat
      if s[p].rev then update(p);
      if x=s[s[p].lc].size+1 then break;
      if x<=s[s[p].lc].size then p:=s[p].lc else
      begin
        dec(x,s[s[p].lc].size+1);
        p:=s[p].rc;
      end;
    until false;
    splay(p);
  end else
  begin
    if x=1 then splay(n+1);
    if x=n+2 then splay(n+2);
  end;
end;

procedure reverse(l,r:longint);
begin
  find(l);
  find(r+2);
  s[s[s[root].lc].rc].rev:=not s[s[s[root].lc].rc].rev;
end;

procedure dfs(t:longint);
begin
  if s[t].rev then update(t);
  if s[t].lc<>0 then dfs(s[t].lc);
  if t<=n then write(s[t].key,' ');
  if s[t].rc<>0 then dfs(s[t].rc);
end;

begin
  readln(n,m);
  root:=0;
  tot:=0;
  for n:=1 to n do insert(n);
  insert(0);
  insert(n+1);
  for m:=1 to m do
  begin
    readln(l,r);
    reverse(l,r);
  end;
  dfs(root);
end.

//=================================

program bzoj_1861;
var s:array[0..80005]of record fa,lc,rc,key,num,size:longint; end;
    root,tot,n,m,i,k,t:longint;
    pos:array[0..80005]of longint;
    cas,cc:char;

procedure update(t:longint);
begin
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
end;

procedure insert(var t:longint;k,num,f:longint);
begin
  if t=0 then
  begin
    inc(tot);
    t:=tot;
    fillchar(s[t],sizeof(s[t]),0);
    s[t].fa:=f;
    s[t].key:=k;
    s[t].num:=num;
    s[t].size:=1;
    exit;
  end;
  if k<s[t].key then insert(s[t].lc,k,num,t) else insert(s[t].rc,k,num,t);
  update(t);
end;

procedure l_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].rc:=s[t].lc;
  if s[t].lc<>0 then s[s[t].lc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].lc:=p;
  s[p].fa:=t;
  update(p);
  update(t);
end;

procedure r_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].lc:=s[t].rc;
  if s[t].rc<>0 then s[s[t].rc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].rc:=p;
  s[p].fa:=t;
  update(p);
  update(t);
end;

procedure splay(t:longint);
begin
  while s[t].fa<>0 do
  if t=s[s[t].fa].lc then r_rotate(t) else l_rotate(t);
  root:=t;
end;

procedure union(lt,rt:longint);
begin
  s[lt].fa:=0;
  while s[lt].rc<>0 do lt:=s[lt].rc;
  splay(lt);
  s[lt].rc:=rt;
  s[rt].fa:=lt;
  update(lt);
  root:=lt;
end;

function rank(t:longint):longint;
begin
  splay(t);
  exit(s[s[root].lc].size-1);
end;

function findrk(t,rk:longint):longint;
begin
  if rk=s[s[t].lc].size+1 then exit(t);
  if rk<=s[s[t].lc].size then exit(findrk(s[t].lc,rk)) else exit(findrk(s[t].rc,rk-s[s[t].lc].size-1));
end;

function mininum(t:longint):longint;
begin
  while s[t].lc<>0 do t:=s[t].lc;
  exit(t);
end;

function maxinum(t:longint):longint;
begin
  while s[t].rc<>0 do t:=s[t].rc;
  exit(t);
end;

procedure delete(t:longint);
begin
  splay(t);
  union(s[root].lc,s[root].rc);
  s[t].lc:=0;
  s[t].rc:=0;
end;

procedure move(x,c:longint);
var pre,nxt,id:longint;
begin
  if c=0 then exit;
  id:=pos[x];
  splay(id);
  delete(id);
  case c of
    -1:begin
      nxt:=root;
      pre:=maxinum(s[root].lc);
    end;
    1:begin
      pre:=mininum(s[root].rc);
      splay(pre);
      nxt:=mininum(s[root].rc);
    end;
    -2:begin
      pre:=mininum(root);
      splay(pre);
      nxt:=mininum(s[root].rc);
    end;
    2:begin
      nxt:=maxinum(root);
      splay(nxt);
      pre:=maxinum(s[root].lc);
    end;
  end;
  splay(pre);
  splay(nxt);
  s[pre].rc:=id;
  s[id].fa:=pre;
  update(id);
  update(pre);
  update(nxt);
end;

begin
  readln(n,m);
  tot:=0;
  root:=0;
  insert(root,0,0,0);
  for i:=1 to n do
  begin
    read(k);
    insert(root,i,k,0);
    splay(s[root].rc);
    pos[k]:=tot;
  end;
  insert(root,n+1,0,0);
  readln;
  for m:=1 to m do
  begin
    read(cas);
    case cas of
      'T':begin
        for i:=1 to 2 do read(cc);
        read(k);
        move(k,-2);
      end;
      'B':begin
        for i:=1 to 5 do read(cc);
        read(k);
        move(k,2);
      end;
      'I':begin
        for i:=1 to 5 do read(cc);
        read(k,t);
        move(k,t);
      end;
      'A':begin
        for i:=1 to 2 do read(cc);
        read(k);
        writeln(rank(pos[k]));
      end;
      'Q':begin
        for i:=1 to 4 do read(cc);
        read(k);
        writeln(s[findrk(root,k+1)].num);
      end;
    end;
    readln;
  end;
end.

//=================================

program bzoj_1507;
var s:array[0..2100000]of record fa,lc,rc,size:longint; ch:char; end;
    root,tot,m,k,i,len:longint;
    cas,cc:char;
    str:array[1..2100000]of char;

procedure update(t:longint);
begin
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
end;

procedure l_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].rc:=s[t].lc;
  if s[t].lc<>0 then s[s[t].lc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[p].fa:=t;
  s[t].lc:=p;
  update(p);
  update(t);
end;

procedure r_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].lc:=s[t].rc;
  if s[t].rc<>0 then s[s[t].rc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[p].fa:=t;
  s[t].rc:=p;
  update(p);
  update(t);
end;

procedure splay(t,aim:longint);
var a:longint;
begin
  a:=s[aim].fa;
  while s[t].fa<>a do
  if t=s[s[t].fa].lc then r_rotate(t) else l_rotate(t);
  if a=0 then root:=t;
end;

procedure build(var t:longint;l,r,fa:longint);
var len,mid:longint;
begin
  mid:=(l+r)>>1;
  if t=0 then
  begin
    inc(tot);
    t:=tot;
    fillchar(s[t],sizeof(s[t]),0);
    s[t].ch:=str[mid];
    s[t].size:=1;
    s[t].fa:=fa;
  end;
  if l<mid then build(s[t].lc,l,mid-1,t);
  if r>mid then build(s[t].rc,mid+1,r,t);
  update(t);
end;

function find(t,rk:longint):longint;
begin
  if rk>=s[root].size then rk:=s[root].size;
  if rk=s[s[t].lc].size+1 then exit(t);
  if rk<=s[s[t].lc].size then exit(find(s[t].lc,rk)) else exit(find(s[t].rc,rk-s[s[t].lc].size-1));
end;

procedure pred(t:longint);
begin
  if s[t].lc=0 then exit;
  t:=s[t].lc;
  while s[t].rc<>0 do t:=s[t].rc;
  splay(t,root);
end;

procedure succ(t:longint);
begin
  if s[t].rc=0 then exit;
  t:=s[t].rc;
  while s[t].lc<>0 do t:=s[t].lc;
  splay(t,root);
end;

function rank(t:longint):longint;
begin
  exit(s[s[t].lc].size+1);
end;

procedure print(t:longint);
begin
  if t=0 then exit;
  print(s[t].lc);
  write(s[t].ch);
  print(s[t].rc);
end;

begin
  readln(m);
  root:=0;
  tot:=0;
  str[1]:=' ';
  str[2]:=' ';
  len:=2;
  build(root,1,2,0);
  for m:=1 to m do
  begin
    read(cas);
    case cas of
      'M':begin
        for i:=1 to 3 do read(cc);
        readln(k);
        splay(find(root,k+1),root);
      end;
      'I':begin
        for i:=1 to 5 do read(cc);
        readln(k);
        len:=0;
        while len<k do
        begin
          while not eoln do
          begin
            inc(len);
            read(str[len]);
          end;
          readln;
        end;
        succ(root);
        splay(s[root].lc,root);
        build(s[s[root].rc].lc,1,len,s[root].rc);
        update(s[root].rc);
        update(root);
      end;
      'D':begin
        for i:=1 to 5 do read(cc);
        readln(k);
        splay(find(root,rank(root)+k+1),s[root].rc);
        s[s[root].rc].lc:=0;
        update(s[root].rc);
        update(root);
      end;
      'G':begin
        read(cc);read(cc);
        readln(k);
        splay(find(root,rank(root)+k+1),s[root].rc);
        print(s[s[root].rc].lc);
        writeln;
      end;
      'P':begin
        read(cc);read(cc);readln(cc);
        pred(root);
      end;
      'N':begin
        read(cc);read(cc);readln(cc);
        succ(root);
      end;
    end;
  end;
end.

//=================================

program bzoj_1500;
const inf=maxlongint shr 2;
var s:array[0..500002]of record lc,rc,fa,key,size,lm,rm,m,sum:longint; rev,sam:boolean; end;
    root,tot,n,m,i,pos,c,cnt,top:longint;
    ch,cc:char;
    sav,rec:array[0..500001]of longint;

function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;

procedure swap(var a,b:longint);
var p:longint;
begin
  p:=a;
  a:=b;
  b:=p;
end;

procedure update(t:longint);
begin
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  s[t].sum:=s[s[t].lc].sum+s[s[t].rc].sum+s[t].key;
  s[t].m:=max(s[s[t].lc].rm+s[s[t].rc].lm+s[t].key,max(s[s[t].lc].m,s[s[t].rc].m));
  s[t].lm:=max(s[s[t].lc].lm,s[s[t].lc].sum+s[t].key+s[s[t].rc].lm);
  s[t].rm:=max(s[s[t].rc].rm,s[s[t].rc].sum+s[t].key+s[s[t].lc].rm);
end;

procedure pushdown(t:longint);
var l,r:longint;
begin
  l:=s[t].lc;
  r:=s[t].rc;
  if s[t].sam then
  begin
    s[t].sam:=false;
    s[t].rev:=false;
    if l<>0 then
    begin
      s[l].key:=s[t].key;
      s[l].sam:=true;
      s[l].sum:=s[l].size*s[l].key;
      if s[l].key>=0 then
      begin
        s[l].lm:=s[l].sum;
        s[l].rm:=s[l].sum;
        s[l].m:=s[l].sum;
      end else
      begin
        s[l].lm:=0;
        s[l].rm:=0;
        s[l].m:=s[l].key;
      end;
    end;
    if r<>0 then
    begin
      s[r].key:=s[t].key;
      s[r].sam:=true;
      s[r].sum:=s[r].size*s[r].key;
      if s[r].key>=0 then
      begin
        s[r].lm:=s[r].sum;
        s[r].rm:=s[r].sum;
        s[r].m:=s[r].sum;
      end else
      begin
        s[r].lm:=0;
        s[r].rm:=0;
        s[r].m:=s[r].key;
      end;
    end;
  end;
  if s[t].rev then
  begin
    s[t].rev:=not s[t].rev;
    s[l].rev:=not s[l].rev;
    s[r].rev:=not s[r].rev;
    swap(s[l].lm,s[l].rm);
    swap(s[l].lc,s[l].rc);
    swap(s[r].lm,s[r].rm);
    swap(s[r].lc,s[r].rc);
    update(t);
  end;
end;

procedure l_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].rc:=s[t].lc;
  if s[t].lc<>0 then s[s[t].lc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[p].fa:=t;
  s[t].lc:=p;
  update(p);
  update(t);
end;

procedure r_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].lc:=s[t].rc;
  if s[t].rc<>0 then s[s[t].rc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[p].fa:=t;
  s[t].rc:=p;
  update(p);
  update(t);
end;

procedure splay(t,aim:longint);
var p:longint;
begin
  p:=s[aim].fa;
  while s[t].fa<>p do
  if t=s[s[t].fa].lc then r_rotate(t) else l_rotate(t);
end;

function build(l,r:longint):longint;
var mid,id:longint;
begin
  if top>0 then
  begin
    id:=rec[top];
    dec(top);
  end else
  begin
    inc(tot);
    id:=tot;
  end;
  mid:=(l+r)shr 1;
  s[id].key:=sav[mid];
  s[id].lc:=0;
  s[id].rc:=0;
  if l=r then
  begin
    s[id].lm:=max(0,s[id].key);
    s[id].rm:=max(0,s[id].key);
    s[id].m:=s[id].key;
    s[id].sum:=s[id].key;
    s[id].size:=1;
    exit(id);
  end;
  if l<mid then
  begin
    s[id].lc:=build(l,mid-1);
    s[s[id].lc].fa:=id;
  end;
  if mid<r then
  begin
    s[id].rc:=build(mid+1,r);
    s[s[id].rc].fa:=id;
  end;
  update(id);
  exit(id);
end;

procedure dispose(t:longint);
begin
  inc(top);
  rec[top]:=t;
  if s[t].lc<>0 then dispose(s[t].lc);
  if s[t].rc<>0 then dispose(s[t].rc);
  fillchar(s[t],sizeof(s[t]),0);
end;

function find(t,rk:longint):longint;
begin
  if rk>s[root].size then rk:=s[root].size;
  if s[t].rev or s[t].sam then pushdown(t);
  if rk=s[s[t].lc].size+1 then exit(t);
  if rk<=s[s[t].lc].size then exit(find(s[t].lc,rk)) else exit(find(s[t].rc,rk-s[s[t].lc].size-1));
end;

procedure insert(pos,cnt:longint);
var st,ed:longint;
begin
  st:=find(root,pos+1);
  ed:=find(root,pos+2);
  splay(st,root);
  root:=st;
  splay(ed,s[root].rc);
  s[s[root].rc].lc:=build(1,cnt);
  s[s[s[root].rc].lc].fa:=s[root].rc;
  update(s[root].rc);
  update(root);
end;

procedure delete(pos,cnt:longint);
var st,ed:longint;
begin
  st:=find(root,pos);
  ed:=find(root,pos+cnt+1);
  splay(st,root);
  root:=st;
  splay(ed,s[root].rc);
  dispose(s[s[root].rc].lc);
  s[s[root].rc].lc:=0;
  update(s[root].rc);
  update(root);
end;

procedure makesame(pos,cnt,c:longint);
var st,ed,p:longint;
begin
  st:=find(root,pos);
  ed:=find(root,pos+cnt+1);
  splay(st,root);
  root:=st;
  splay(ed,s[root].rc);
  p:=s[s[root].rc].lc;
  s[p].sam:=true;
  s[p].key:=c;
  s[p].sum:=s[p].size*s[p].key;
  if s[p].key>=0 then
  begin
    s[p].lm:=s[p].sum;
    s[p].rm:=s[p].sum;
    s[p].m:=s[p].sum;
  end else
  begin
    s[p].lm:=0;
    s[p].rm:=0;
    s[p].m:=s[p].key;
  end;
  update(s[root].rc);
  update(root);
end;

procedure reverse(pos,cnt:longint);
var st,ed,p:longint;
begin
  st:=find(root,pos);
  ed:=find(root,pos+cnt+1);
  splay(st,root);
  root:=st;
  splay(ed,s[root].rc);
  p:=s[s[root].rc].lc;
  s[p].rev:=true;
  swap(s[p].lm,s[p].rm);
  swap(s[p].lc,s[p].rc);
  update(s[root].rc);
  update(root);
end;

function query(pos,cnt:longint):longint;
var st,ed:longint;
begin
  st:=find(root,pos);
  ed:=find(root,pos+cnt+1);
  splay(st,root);
  root:=st;
  splay(ed,s[root].rc);
  exit(s[s[s[root].rc].lc].sum);
end;

begin
  readln(n,m);
  for i:=1 to n do read(sav[i]);
  sav[0]:=-inf;
  sav[n+1]:=-inf;
  s[0].m:=-inf;
  top:=0;
  root:=build(0,n+1);
  readln;
  for m:=1 to m do
  begin
    for i:=1 to 3 do read(ch);
    case ch of
      'S':begin
        for i:=1 to 3 do read(cc);
        read(pos,cnt);
        for i:=1 to cnt do read(sav[i]);
        insert(pos,cnt);
      end;
      'L':begin
        for i:=1 to 3 do read(cc);
        read(pos,cnt);
        delete(pos,cnt);
      end;
      'K':begin
        for i:=1 to 6 do read(cc);
        read(pos,cnt,c);
        makesame(pos,cnt,c);
      end;
      'V':begin
        for i:=1 to 4 do read(cc);
        read(pos,cnt);
        reverse(pos,cnt);
      end;
      'T':begin
        for i:=1 to 4 do read(cc);
        read(pos,cnt);
        writeln(query(pos,cnt));
      end;
      'X':begin
        for i:=1 to 4 do read(cc);
        writeln(s[root].m);
      end;
    end;
    readln;
  end;
end.

//=================================

program bzoj_1012;
var s:array[0..200000]of record fa,lc,rc,key,size,max:longint; end;
    m,d,k,tot,root,lst:longint;
    cas:char;

function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;

procedure update(t:longint);
begin
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  s[t].max:=max(s[t].key,max(s[s[t].lc].max,s[s[t].rc].max));
end;

procedure l_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].rc:=s[t].lc;
  if s[t].lc<>0 then s[s[t].lc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].lc:=p;
  s[p].fa:=t;
  update(p);
  update(t);
end;

procedure r_rotate(t:longint);
var p:longint;
begin
  p:=s[t].fa;
  s[p].lc:=s[t].rc;
  if s[t].rc<>0 then s[s[t].rc].fa:=p;
  s[t].fa:=s[p].fa;
  if s[p].fa<>0 then
  if p=s[s[p].fa].lc then s[s[p].fa].lc:=t else s[s[p].fa].rc:=t;
  s[t].rc:=p;
  s[p].fa:=t;
  update(p);
  update(t);
end;

procedure insert(var t:longint;key,fa:longint);
begin
  if t=0 then
  begin
    inc(tot);
    t:=tot;
    fillchar(s[t],sizeof(s[t]),0);
    s[t].fa:=fa;
    s[t].key:=key;
    s[t].size:=1;
    s[t].max:=key;
    exit;
  end;
  if key<s[t].key then insert(s[t].lc,key,t) else insert(s[t].rc,key,t);
  update(t);
end;

function findrk(t,rk:longint):longint;
begin
  if rk=s[s[t].lc].size+1 then exit(t);
  if rk<=s[s[t].lc].size then exit(findrk(s[t].lc,rk)) else exit(findrk(s[t].rc,rk-s[s[t].lc].size-1));
end;

procedure splay(t:longint);
begin
  while s[t].fa<>0 do
  if t=s[s[t].fa].lc then r_rotate(t) else l_rotate(t);
  root:=t;
end;

begin
  readln(m,d);
  lst:=0;
  root:=0;
  tot:=0;
  insert(root,-maxlongint,0);
  insert(s[root].rc,-maxlongint,root);
  update(root);
  for m:=1 to m do
  begin
    read(cas);
    case cas of
      'Q':begin
        readln(k);
        splay(findrk(root,s[root].size-k-1));
        lst:=s[s[root].rc].max;
        writeln(lst);
      end;
      'A':begin
        readln(k);
        k:=(k+lst)mod d;
        splay(findrk(root,s[root].size-1));
        insert(s[s[root].rc].lc,k,s[root].rc);
        update(s[root].rc);
        update(root);
      end;
    end;
  end;
end.

//=================================

program bzoj_1056;
type str=array[1..10]of char;
const mo=10000007;
var s:array[0..300010]of record lc,rc,size,time,key:longint; nam:str; end;
    root,tot,m,k,len,cnt:longint;
    cas,c:char;
    temp:str;
    hs:array[0..300010]of record key,time,pre:longint; nam:str; end;
    nxt:array[0..mo+100]of longint;
 
function big(t,key,time:longint):boolean;
begin
  if key>s[t].key then exit(true);
  if (key=s[t].key)and(time<s[t].time) then exit(true);
  exit(false);
end;
 
function sam(s1,s2:str):boolean;
var i:longint;
begin
  for i:=1 to 10 do
  if s1[i]<>s2[i] then exit(false);
  exit(true);
end;
 
procedure val(s:str;var k:longint;len:longint);
var i:longint;
begin
  k:=0;
  for i:=1 to len do
  k:=k*10+ord(s[i])-ord('0');
end;
 
function hash(nam:str):longint;
var i:longint;
begin
  hash:=1;
  for i:=1 to length(nam) do hash:=(hash*131+ord(nam[i]))mod mo;
end;
 
procedure l_rotate(var t:longint);
var k:longint;
begin
  k:=s[t].rc;
  s[t].rc:=s[k].lc;
  s[k].lc:=t;
  s[k].size:=s[t].size;
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  t:=k;
end;
 
procedure r_rotate(var t:longint);
var k:longint;
begin
  k:=s[t].lc;
  s[t].lc:=s[k].rc;
  s[k].rc:=t;
  s[k].size:=s[t].size;
  s[t].size:=s[s[t].lc].size+s[s[t].rc].size+1;
  t:=k;
end;
 
procedure maintain(var t:longint;flag:boolean);
begin
  if not flag then
  begin
    if s[s[s[t].lc].lc].size>s[s[t].rc].size then r_rotate(t) else
    if s[s[s[t].lc].rc].size>s[s[t].rc].size then
    begin
      l_rotate(s[t].lc);
      r_rotate(t);
    end else exit;
  end else
  begin
    if s[s[s[t].rc].rc].size>s[s[t].lc].size then l_rotate(t) else
    if s[s[s[t].rc].lc].size>s[s[t].lc].size then
    begin
      r_rotate(s[t].rc);
      l_rotate(t);
    end else exit;
  end;
  maintain(s[t].lc,false);
  maintain(s[t].rc,true);
  maintain(t,false);
  maintain(t,true);
end;
 
function find(t,k,time:longint):boolean;
begin
  if t=0 then exit(false);
  if (s[t].key=k)and(s[t].time=time) then exit(true);
  if big(t,k,time) then exit(find(s[t].lc,k,time)) else exit(find(s[t].rc,k,time));
end;
 
procedure insert(var t:longint;k,time:longint;nam:str);
begin
  if t=0 then
  begin
    inc(tot);
    t:=tot;
    fillchar(s[t],sizeof(s[t]),0);
    s[t].size:=1;
    s[t].key:=k;
    s[t].time:=time;
    s[t].nam:=nam;
  end else
  begin
    inc(s[t].size);
    if big(t,k,time) then
    begin
      insert(s[t].lc,k,time,nam);
      maintain(t,false);
    end else
    begin
      insert(s[t].rc,k,time,nam);
      maintain(t,true);
    end;
  end;
end;
 
function delete(var t:longint;k,time:longint):longint;
var d:longint;
begin
  dec(s[t].size);
  if (k=s[t].key)and(time=s[t].time)or(big(t,k,time)and(s[t].lc=0))or(not big(t,k,time)and(s[t].rc=0)) then
  begin
    delete:=t;
    if (s[t].lc=0)or(s[t].rc=0) then t:=s[t].lc+s[t].rc else
    begin
      d:=delete(s[t].lc,-maxlongint,maxlongint);
      s[t].key:=s[d].key;
      s[t].time:=s[d].time;
      s[t].nam:=s[d].nam;
    end;
  end else
  if big(t,k,time) then exit(delete(s[t].lc,k,time)) else exit(delete(s[t].rc,k,time));
end;
 
procedure modify(nam:str;key,time:longint);
var p,h,pre:longint;
begin
  h:=hash(nam);
  p:=nxt[h];
  pre:=p;
  while p<>0 do
  begin
    if sam(hs[p].nam,nam)then
    begin
      delete(root,hs[p].key,hs[p].time);
      hs[p].key:=key;
      hs[p].time:=time;
      insert(root,key,time,nam);
      exit;
    end;
    p:=hs[p].pre;
  end;
  inc(cnt);
  hs[cnt].time:=time;
  hs[cnt].key:=key;
  hs[cnt].nam:=nam;
  hs[cnt].pre:=pre;
  nxt[h]:=cnt;
  insert(root,key,time,nam);
end;
 
function findrk(t,rk:longint):longint;
begin
  if rk=s[s[t].lc].size+1 then exit(t);
  if rk<=s[s[t].lc].size then exit(findrk(s[t].lc,rk)) else exit(findrk(s[t].rc,rk-s[s[t].lc].size-1));
end;
 
procedure solve(rk:longint);
var ed,i,j,p:longint;
begin
  ed:=rk+9;
  if s[root].size<ed then ed:=s[root].size;
  for i:=rk to ed do
  begin
    p:=findrk(root,i);
    for j:=1 to 10 do if s[p].nam[j] in ['A'..'Z'] then write(s[p].nam[j]) else break;
    if i<>ed then write(' ');
  end;
  writeln;
end;
 
function rank(t,k,time:longint):longint;
begin
  if (s[t].key=k)and(s[t].time=time) then exit(s[s[t].lc].size+1);
  if big(t,k,time) then exit(rank(s[t].lc,k,time)) else exit(rank(s[t].rc,k,time)+s[s[t].lc].size+1);
end;
 
procedure query(nam:str);
var h,p:longint;
begin
  h:=hash(nam);
  p:=nxt[h];
  while p<>0 do
  begin
    if sam(hs[p].nam,nam) then with hs[p] do
    begin
      writeln(rank(root,key,time));
      exit;
    end;
    p:=hs[p].pre;
  end;
end;
 
begin
  readln(m);
  fillchar(nxt,sizeof(nxt),0);
  fillchar(hs,sizeof(hs),0);
  root:=0;
  tot:=0;
  cnt:=0;
  for m:=1 to m do
  begin
    read(cas);
    len:=0;
    fillchar(temp,sizeof(temp),0);
    case cas of
      '+':begin
        read(c);
        while c<>' ' do
        begin
          inc(len);
          temp[len]:=c;
          read(c);
        end;
        read(k);
        modify(temp,k,m);
      end;
      '?':begin
        read(c);
        while c in ['A'..'Z','0'..'9'] do
        begin
          inc(len);
          temp[len]:=c;
          read(c);
        end;
        if temp[1] in ['0'..'9'] then
        begin
          val(temp,k,len);
          solve(k);
        end else query(temp);
      end;
    end;
    readln;
  end;
end.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值