bzoj1455 左偏堆

来源:互联网 发布:java -d path 编辑:程序博客网 时间:2024/06/11 20:49

1455: 罗马游戏

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1977  Solved: 856
[Submit][Status][Discuss]

Description

罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)

Input

第一行一个整数n(1<=n<=1000000)。n表示士兵数,m表示总命令数。 第二行n个整数,其中第i个数表示编号为i的士兵的分数。(分数都是[0..10000]之间的整数) 第三行一个整数m(1<=m<=100000) 第3+i行描述第i条命令。命令为如下两种形式: 1. M i j 2. K i

Output

如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)

裸左偏堆!在这里感谢wyx大佬!
贴上代码
var
  live:array[0..1000005]of boolean;
  x,y,l,r,v,d,fa:array[0..1000005]of longint;
  n,i,j,k,t,m:longint;
  c:array[0..1000005]of char;
  s:string;
procedure change(var x,y:longint);
var
  t:longint;
begin
  t:=x;
  x:=y;
  y:=t;
end;
function getfa(x:longint):longint;
begin
  while fa[x]>0 do x:=fa[x];
  exit(x);
end;
function merge(x,y:longint):longint;
begin
  if x=0 then exit(y);
  if y=0 then exit(x);
  if (v[x]>v[y])or((v[x]=v[y])and(x>y)) then change(x,y);
  r[x]:=merge(r[x],y);
  fa[r[x]]:=x;
  if d[l[x]]<d[r[x]] then change(l[x],r[x]);
  d[x]:=d[r[x]]+1;
  merge:=x;
end;
begin
  readln(n);
  d[0]:=-1;
  for i:=1 to n do
  begin
    //fa[i]:=i;
    live[i]:=true;
    read(v[i]);
    d[i]:=0;
  end;
  readln(m);
  for i:=1 to m do
  begin
    read(c[i]);
    if c[i]='M' then readln(x[i],y[i])
                else readln(x[i]);
  end;
  for i:=1 to m do
  begin
    if c[i]='M'
      then begin
             if (live[x[i]]=false)or(live[y[i]]=false)or(getfa(x[i])=getfa(y[i])) then continue;
             merge(getfa(x[i]),getfa(y[i]));
             //fa[getfa(x[i])]:=merge(getfa(x[i]),getfa(y[i]));
             //fa[getfa(y[i])]:=fa[getfa(x[i])];
           end
      else begin
             if live[x[i]]=false then begin writeln('0');continue;end;
             t:=getfa(x[i]);
             live[t]:=false;
             fa[l[t]]:=0;
             fa[r[t]]:=0;
             merge(l[t],r[t]);
             //fa[t]:=merge(l[t],r[t]);
             //fa[fa[t]]:=fa[t];
             writeln(v[t]);
           end;
  end;
end.