码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 11525

时间:2015-01-15 16:09:18      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:数据结构   线段树   康托展开   排列   

UVA 11525
(一种通过康托展开求排列的方法)
Problem
  给定一个1-K的排列的康托展开形式,即S1*(K-1)! + S2*(K-2)! + S3*(K-3)! +......+ SK(K-K)!;输出排列。

Limits
Time Limit(ms); 3000
Memory Limit(MB): No Limit
K: [1, 50000]
Si: [0, K - i]

Solution
  根据康托展开的定义,可以看出,Si 表示的是当前比排列 i 位置的数小且没有在[1, i-1] 位置出现过的数的个数(具体可以参照百度百科或wiki)。问题则可以转化为:起初K个人排队,1,2,3,...,K;每次给定一个S,找到当前排第S位的人,让其出列,再如此循环,要求每次都准确找到排第S位的人是哪一个人。注意每一次S都可能不一样,出列后的人不再属于当前队伍。怎么做?用线段树动态查找就可以实现。

More
  定义线段树每个结点表示不同的区间,根结点表示总区间,将区间二分成左孩子和右孩子,表示左半区间和右半区间,每个结点有一个域值,表示当前区间中含有的人数。起初,叶子结点域值为1,表示含有1个人,父亲域值等于左右孩子域值之和。Si +1实则表示当前是第S个人,用线段树动态查找,若左孩子域值大于等于S,则往左孩子查找,S不变;否则,往右孩子查找,S=S-左孩子域值。直到查到叶子结点为止,返回区间左端点(或右端点)。
  用二分+线段树也可以实现,但复杂度为O(K*logK*logK)。

Complexity
Time Complexity: O(K*logK)
Memory Complexity: O(4*K)

Source

Code


UVA 11525

标签:数据结构   线段树   康托展开   排列   

原文地址:http://blog.csdn.net/uestc_peterpan/article/details/42741309

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!