bzoj 1862: [Zjoi2006]GameZ游戏排名系统 & bzoj 1056: [HAOI2008]排名系统

傻叉了一晚上,把t打成x,然后这题神奇在于输出一段数,不足的不用输出,一开始我的是直接找没有后面就退,然后这样会格式错误囧……然后最后zj的还卡了下空间,于是不用string就过了……string毁一生……

 

 

const
  maxn=250550;
  mm=2000000;
var
  hash,size,left,right,fix,value,time,num,shi,cost:array[0..maxn]of longint;
  who:array[0..maxn,0..10]of longint;
  trie:array[0..maxn,'A'..'Z']of longint;
  n,tot,total,peo,u,i,j,k,ii,t:longint;
  s:string;
  ch:char;
  
procedure lt(var t:longint);
var
  k:longint;
begin
  k:=right[t];
  right[t]:=left[k];
  left[k]:=t;
  size[k]:=size[t];
  size[t]:=size[left[t]]+size[right[t]]+1;
  t:=k;
end;
  
procedure rt(var t:longint);
var
  k:longint;
begin
  k:=left[t];
  left[t]:=right[k];
  right[k]:=t;
  size[k]:=size[t];
  size[t]:=size[left[t]]+size[right[t]]+1;
  t:=k;
end;
  
procedure insert(var t:longint;y,z,l:longint);
begin
  if t=0 then begin
    inc(total);
    t:=total;
    value[t]:=y;
    fix[t]:=random(mm);
    time[t]:=z;
    hash[t]:=l;
    left[t]:=0;
    right[t]:=0;
    size[t]:=1;
    exit;
  end;
  inc(size[t]);
  if y<=value[t] then begin
    insert(right[t],y,z,l);
    if fix[right[t]]<fix[t] then lt(t);
  end
  else begin
    insert(left[t],y,z,l);
    if fix[left[t]]<fix[t] then rt(t);
  end;
end;
  
procedure delete(var t:longint;y,z:longint);
begin
  if t=0 then exit;
  dec(size[t]);
  if (value[t]=y) and (time[t]=z) then begin
    if left[t]=0 then t:=right[t]
    else
    if right[t]=0 then t:=left[t]
    else
      if fix[right[t]]<fix[left[t]] then begin
        lt(t);
        delete(left[t],y,z);
      end
      else begin
        rt(t);
        delete(right[t],y,z);
      end;
    exit;
  end;
  if (y>value[t]) or (y=value[t]) and (z<time[t])
    then delete(left[t],y,z)
    else delete(right[t],y,z);
end;
  
function rank(t,y,z:longint):longint;
begin
  if t=0 then exit(0);
  if (y=value[t]) and (z=time[t]) then exit(size[left[t]]+1);
  if (y>value[t]) or (y=value[t]) and (z<time[t]) then exit(rank(left[t],y,z));
  exit(size[left[t]]+1+rank(right[t],y,z));
end;
  
procedure outs(x:longint);
var
  i:longint;
begin
  for i:=1 to who[x][0] do
    write(chr(who[x][i]));
end;
  
procedure find(t,x:longint;var y:longint);
begin
  if (t=0) or (y=0) then exit;
  if x<=size[left[t]] then begin
    find(left[t],x,y);
    if y>0 then begin
      dec(y);
      if y=0 then begin
        outs(hash[t]);
        writeln;
        exit;
      end;
      outs(hash[t]);
      write(' ');
      find(right[t],1,y);
    end;
  end
  else begin
    if x=size[left[t]]+1 then begin
      dec(y);
      if y=0 then begin
        outs(hash[t]);
        writeln;
        exit;
      end;
      outs(hash[t]);
      write(' ');
      inc(x);
    end;
    find(right[t],x-size[left[t]]-1,y);
  end;
end;
  
begin
  readln(n);
  randomize;
  peo:=0;
  total:=0;
  tot:=0;
  for ii:=1 to n do begin
    read(ch);
    if ch='+' then begin
      u:=0;
      s:='';
      read(ch);
      repeat
        s:=s+ch;
        if trie[u][ch]=0 then begin
          inc(tot);
          trie[u][ch]:=tot;
        end;
        u:=trie[u][ch];
        read(ch);
      until ch=' ';
      readln(j);
      if num[u]=0 then begin
        inc(peo);
        num[u]:=peo;
        cost[peo]:=j;
        shi[peo]:=ii;
        who[peo][0]:=length(s);
        for i:=1 to who[peo][0] do who[peo][i]:=ord(s[i]);
        insert(t,j,ii,peo);
      end
      else begin
        delete(t,cost[num[u]],shi[num[u]]);
        cost[num[u]]:=j;
        shi[num[u]]:=ii;
        insert(t,j,ii,num[u]);
      end;
    end
    else
    if ch='?' then begin
      readln(s);
      if (ord(s[1])>=65) and (ord(s[1])<=90) then begin
        u:=0;
        for i:=1 to length(s) do u:=trie[u][s[i]];
        writeln(rank(t,cost[num[u]],shi[num[u]]));
      end
      else begin
        val(s,i);
        j:=10;
        if i+j>peo then j:=peo-i+1;
        find(t,i,j);
      end;
    end;
  end;
end.
View Code

 

posted @ 2015-03-22 22:01  Macaulish  阅读(...)  评论(...编辑  收藏