博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj2182
阅读量:7165 次
发布时间:2019-06-29

本文共 813 字,大约阅读时间需要 2 分钟。

首先容易知道,最后一个数是最容易确定的,于是从后往前确定

对于位置j,它的数就是1~n中剩余数的第a[j]+1小的数

这当然可以用平衡数做,复杂度为O(nlogn)

有没有更简洁得算法?树状数组+二分

1 var v:array[0..8010] of boolean; 2     c,ans,a:array[0..8010] of longint; 3     i,j,n:longint; 4 function lowbit(x:longint):longint; 5   begin 6     exit(x and (-x)); 7   end; 8  9 function sum(x:longint):longint;10   begin11     sum:=0;12     while x>0 do13     begin14       sum:=sum+c[x];15       x:=x-lowbit(x);16     end;17   end;18 19 function kth(t:longint):longint;20   var l,r,m,p:longint;21   begin22     l:=1;23     r:=n;24     while l<=r do25     begin26       m:=(l+r) shr 1;27       p:=sum(m);       //统计二分得到的这个数前面有几个比它小的28       if (p=t) and not v[m] then exit(m);   //注意不要忘记判断这个数是否存在29       if p
View Code

总的复杂度为O(n*logn*logn)虽然慢了一点,但是编程复杂度大大下降

 

转载于:https://www.cnblogs.com/phile/p/4473281.html

你可能感兴趣的文章