【Algorithm】逆序数的分治求解
逆序数的分治求解,时间复杂度O(nlgn)。基本思想是在归并排序的基础上加逆序计数。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <ctime> 6 using namespace std; 7 8 #define MAXN 100005 9 10 int a[MAXN], b[MAXN]; 11 int c[MAXN]; 12 int ans, n; 13 14 void merge(int *a, int l, int r) { 15 int mid = (l+r)>>1; 16 int i = l, j = mid+1; 17 int n = 0; 18 19 while (i<=mid && j<=r) { 20 if (a[i] <= a[j]) { 21 c[n++] = a[i++]; 22 } else { 23 c[n++] = a[j++]; 24 ans += (mid-i+1); 25 } 26 } 27 while (i <= mid) 28 c[n++] = a[i++]; 29 while (j <= r) 30 c[n++] = a[j++]; 31 for (i=0, j=l; i<n; ++i, ++j) 32 a[j] = c[i]; 33 } 34 35 void mergeSort(int *a, int l, int r) { 36 int mid = (l+r)>>1; 37 38 if (l >= r) 39 return ; 40 mergeSort(a, l, mid); 41 mergeSort(a, mid+1, r); 42 merge(a, l, r); 43 } 44 45 void bruteSolve(int *b, int l, int r) { 46 int i, j; 47 48 for (i=l; i<=r; ++i) { 49 for (j=l; j<=i; ++j) { 50 if (b[j] > b[i]) 51 ++ans; 52 } 53 } 54 } 55 56 void init() { 57 int i; 58 59 n = rand()%(MAXN-1)+1; 60 for (i=1; i<=n; ++i) { 61 a[i] = rand(); 62 b[i] = a[i]; 63 } 64 } 65 66 void solve() { 67 clock_t beg, end; 68 int tmp; 69 70 ans = 0; 71 beg = clock(); 72 mergeSort(a, 1, n); 73 end = clock(); 74 printf("nlgn: ans = %d\n", ans); 75 printf(" time = %.2lf\n", (double)(end-beg)/CLOCKS_PER_SEC); 76 77 tmp = ans; 78 ans = 0; 79 beg = clock(); 80 bruteSolve(b, 1, n); 81 end = clock(); 82 printf("n*n : ans = %d\n", ans); 83 printf(" time = %.2lf\n", (double)(end-beg)/CLOCKS_PER_SEC); 84 85 if (tmp != ans) 86 printf("**** wrong ****\n"); 87 printf("\n"); 88 } 89 90 int main() { 91 int t = 30; 92 93 while (t--) { 94 init(); 95 solve(); 96 } 97 98 return 0; 99 }
转载于:https://www.cnblogs.com/bombe1013/p/4231839.html
【Algorithm】逆序数的分治求解相关推荐
- 归并算法经典应用——求解逆序数
本文始发于个人公众号:TechFlow,原创不易,求个关注 在之前介绍线性代数行列式计算公式的时候,我们曾经介绍过逆序数:我们在列举出行列式的每一项之后,需要通过逆序数来确定这一项符号的正负性.如果有 ...
- 求排列的逆序数(分治)
考虑1,2,-,n (n <= 100000)的排列i1,i2,-,in,如果其中存在j,k,满足 j < k 且 ij > ik, 那么就称(ij,ik)是这个排列的一个逆序. 一 ...
- 光影切割问题之求解逆序数
1. 问题 编程之美1.7光影切割问题可以概括为: 设有两条完全相同的垂直方向上的两条长度相同的线段a和b,且它们对应的端点在同一水平线上. 已知:在这两条线段之间存在n条线段,且每条线段 ...
- 分治递归逆序数_[模板] 归并排序 逆序数 分治
归并排序 图来自维基 递归调用的过程需要在脑中模拟清楚 然后是代码的细节问题 多复习多理解 刘汝佳版 #include using namespace std; const int MAXN = 1e ...
- 逆序数问题,用归并排序而非树状数组求解
逆序数,结合归并排序. 之前一直用树状数组写的,今天发现归并排序也很好写. https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0e ...
- 洛谷P2717 寒假作业(cdq分治+归并排序求逆序数)
2020.6.13 君子做事得有担当,这个题目我确实不太明白什么意思,只会O(N^2)的朴素解法,看了下题解才发现有逆序数的弟弟顺序数,用归并就过了?? 先去打cf div2,等会再来研究 代码: # ...
- 递归/归并:count of smaller numbers求逆序数
已知数组nums,求新数组count,count[i]代表了在nums[i]右侧且比 nums[i]小的元素个数. 例如: nums = [5, 2, 6, 1], count = [2, 1, 1, ...
- 逆序数2 HDOJ 1394 Minimum Inversion Number
题目传送门 1 /* 2 求逆序数的四种方法 3 */ 1 /* 2 1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]. ...
- 逆序数问题(归并排序,C++)
在求解八数码问题时,因为要进行逆序数的计算判断两个结点的可达性,同奇偶的逆序数才能可达.如果只是八数,暴力解法还好,当数字多了之后如何知道逆序数呢. 题目描述 通过计算八数码节点的逆序数判断.如果一对 ...
最新文章
- python 控制库_python中实现自动化控制pyautogui库使用方法介绍
- YUV420转YUV444 , YUV420转RGB
- WP7 应用数据存储Tombstoning(墓碑化)篇
- Kuebernetes之DaemonSet
- Google开源的AR/VR开发库Lullaby
- linux mysql 释放x锁_MySQL 加锁处理分析-转载
- sql连表查询找不到关联字段时?
- SilverLight跨域访问及其常用的几种解决方法
- Windows下,Unicode、UTF8,GBK(GB2312)互转
- 用ntsd -c q -p PID 杀进程
- star法则java简历_在简历中使用STAR法则
- ElasticSearch版本与Jar包冲突
- android系统9有OTG功能吗,随身HiFi 安卓OTG功能在音频上的妙用
- Js学习心得和思考方法
- MySQL复制 slave_exec_mode 参数IDEMPOTENT 说明
- ios15.6RC-15.7.1系统降级iOS14,适用于checkm8机型
- HP Laserjet1010网络打印机安装 win7 64bit
- echart 热搜词云(字符云)的制作以及遇到颜色不会随即变得bug
- Kafka系列之:增加Kafka节点扩展Kafka集群
- zz:使用Monkeyrunner进行Android自动化的总结