• poj2828


    很容易想到一种动态的做法:平衡树……

    或者是二分+树状数组

    但,前者编程复杂度较大,而且据说会被卡(没试过);后者理论上超时(据说可以擦边过?);

    所以要尝试新的算法;

    倒着考虑,显然最后一个对象的位置是最容易确定,顺带着,容易发现,

    在第i个人后插入,就是在当前队列中前面有i个空位的空位置;

    于是还是可以用平衡数……

    当然更简单快捷的方法是线段树,每个节点表示这个区间还有的空位数;

    然后类比平衡树的查找k大,很快就能写成

     1 var tree:array[0..600010] of longint;
     2     p,a,w:array[0..600010] of longint;
     3     n,i:longint;
     4 
     5 procedure build(i,l,r:longint);
     6   var m:longint;
     7   begin
     8     tree[i]:=r-l+1;
     9     m:=(l+r) shr 1;
    10     if l<>r then
    11     begin
    12       build(i*2,l,m);
    13       build(i*2+1,m+1,r);
    14     end;
    15   end;
    16 
    17 function ask(i,l,r,k:longint):longint;
    18   var m:longint;
    19   begin
    20     if l=r then
    21     begin
    22       tree[i]:=0;
    23       exit(l);
    24     end;
    25     m:=(l+r) shr 1;
    26     if tree[i*2]>k then
    27     begin
    28       dec(tree[i*2]);      //在查找的过程中顺便把区间空位数更新
    29       exit(ask(i*2,l,m,k));
    30     end
    31     else begin
    32       dec(tree[i*2+1]);
    33       exit(ask(i*2+1,m+1,r,k-tree[i*2]));   //有没有觉得很平衡树找区间k值神似
    34     end;
    35   end;
    36 
    37 begin
    38   while not eoln do
    39   begin
    40     readln(n);
    41     fillchar(tree,sizeof(tree),0);
    42     build(1,1,n);
    43     for i:=1 to n do
    44       readln(p[i],a[i]);
    45     for i:=n downto 1 do
    46       w[i]:=ask(1,1,n,p[i]);     //w代表每个点的位置
    47     for i:=1 to n do
    48       p[w[i]]:=a[i];
    49     for i:=1 to n do
    50     begin
    51       write(p[i]);
    52       if i<>n then write(' '); //注意别PE了
    53     end;
    54     writeln;
    55   end;
    56 end.
    View Code
  • 相关阅读:
    数据库基础——EXISTS和IN
    C#基础——加密
    C#基础——派生和继承
    SQL Server——报表服务
    SQL Server——SQL Server Profiler
    UML基础——UML简介和历史
    C#基础——密码加密
    C#(ASP.NET)错误: 无法获取属性“0”的值: 对象为 null 或未定义 关键字 'user' 附近有语法错误。
    SQL Server——存储过程
    链表的声明及操作
  • 原文地址:https://www.cnblogs.com/phile/p/4473279.html
Copyright © 2020-2023  润新知