博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ USACO 2018 OPEN ] Out of Sorts (Platinum)
阅读量:5354 次
发布时间:2019-06-15

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

\(\\\)


对一长为\(N\)的数列\(A\)排序,不保证数列元素互异:

  • 数列\(A\)\(A[1...i]\)的最大值不大于\(A[i+1…N]\)的最小值,我们就称元素\(i\)\(i+1\)之间的位置为一个分隔点.

  • 当数列未排好序时,将每一个由分隔点分出的区间单独进行一次顺序扫描的冒泡排序,循环至数列排好序。

  • 形式化的代码可以描述成:

    work_counter = 0bubble_sort_pass (A) {   for i = 0 to length(A)-2      if A[i] > A[i+1], swap A[i] and A[i+1]}quickish_sort (A) {   if length(A) = 1, return   do {      work_counter = work_counter + length(A)      bubble_sort_pass(A)   } while (no partition points exist in A)    divide A at all partition points;    recursively quickish_sort each piece}

求退出循环后\(work\_counter\)的值。

  • \(N\in [0,10^5]\)\(A_i\in [0,10^9]\)

\(\\\)

\(Solution\)


  • 注意到由定义的分隔点分开的每一个区间内,所有元素只会在这一区间内交换,而不会越过分隔点,所以对每一个区间单独冒泡排序与对整个数列冒泡排序是一样的。

  • 所以问题中计数的递归区间总长度,其实是每一个数字被比较的次数之和,其实就是每个数字被递归的层数之和。当一个数字不再被递归计算,当且仅当区间长度为\(1\),即左右都产生了分隔点。于是问题变为:计算每一个数左右都产生分隔点所需的递归次数之和。

  • 每一个数左右都产生分隔点的递归次数又可以看做两个分隔点产生的时间取\(max\),于是只需统计每一个分隔点产生的递归层数。

  • 回到分隔点定义,一个分割点产生,只需要两侧的元素都正确的分开,而不是两侧都排好序。所以一个分隔点产生的时间,是所有应该在左区间的右区间的数移到左区间的时间,和所有应该在右区间的左区间的数移到右区间的时间取最大值。注意到是单向冒泡排序,所以排序的瓶颈在于应当向前移动的那些数字,因为它们每次只会向前移动一个位置。所以我们需要统计离分隔点最远的应移到左区间的点,到分隔点的距离。

  • 于是排序后第一遍扫描统计每一个分隔点产生时间,第二遍扫描累加答案即可。要注意即使一个元素开始就在应该在的地方,即左右分隔点产生时间都为\(0\),也应该计数,因为运行代码中,开始需要将数列扫描一遍来确定是否需要递归。

\(\\\)

\(Code\)


#include
#include
#include
#include
#include
#include
#include
#define N 100010#define R register#define gc getcharusing namespace std;typedef long long ll; inline ll rd(){ ll x=0; bool f=0; char c=gc(); while(!isdigit(c)){if(c=='-')f=1;c=gc();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();} return f?-x:x;} ll n,ans=1,t[N];struct seq{ll x,p;}s[N]; inline bool cmp(seq x,seq y){ return x.x==y.x?x.p

转载于:https://www.cnblogs.com/SGCollin/p/9662098.html

你可能感兴趣的文章
【iOS开发-68】APP下载案例:利用tableView自带的cell布局+缓存池cell复用时注意button状态的检查...
查看>>
《Genesis-3D开源游戏引擎-FQA常见问题解答》2014年01月10号版本
查看>>
Java 编程下实现随机无重复数字功能
查看>>
Android 编程下的代码混淆
查看>>
animation属性
查看>>
页内的模块和组件抽象规划经验
查看>>
安全-分析深圳电信的新型HTTP劫持方式
查看>>
将Centos的yum源更换为国内的阿里云源
查看>>
git diff 的用法
查看>>
HiPAC高性能规则匹配算法之查找过程
查看>>
layoutSubviews总结
查看>>
oracle在imp订单具体解释
查看>>
Java 中队列的使用
查看>>
博客新家来了!!!
查看>>
Python 列表推导实例
查看>>
[leetcode]28. Implement strStr()实现strStr()
查看>>
VMware虚拟机在局域网联网的设置方法
查看>>
python ConfigParser模块get方法简介
查看>>
几种开源的TCP/IP协议栈分析
查看>>
购书打折
查看>>