1.暴力 [代码]: 1 /*HDU1394暴力写法*/ 2 #include <iostream> 3 #include <string.h> 4 #include <stdio.h> 5 6 using namespace std; 7 8 int A[50005]; 9 int Low[50005],Up[50005]; 10 int main(){ 11 int n; 12 while(~scanf("%d",&n)){ 13 int
本文比较 数状数组,线段树,还有一种unnamed的数状结构,在求逆序数中的运行效率. 给定数组a,如果有i, j, i < j且a[i] > a[j],我们称之为一个逆序(反序),求逆序数即找出这样的i,j对的数目.如果通过交换相邻元素来对数组排序,那么逆序数正好是最少的交换次数.长度为n的排列,其逆序数的期望是n(n-1)/4,方差是n(2n+5)(n-1)/72.逆序数的平均数可以大概视为n^2/4,标准差大概视为(1/6)n^(3/2). 经典的求逆序数的算法可以由归并排序给出,但是在
逆序对 对于一个数列\(a_1...a_n\),定义一有序对\((i,j)\)当且仅当\(i<j\)且\(a_i>a_j\)为逆序对.接着我们来考虑怎么求 *1. 归并排序 回顾归并排序的过程,将当且的数列\([l,r]\)分成两个长度相等的部分\([l,mid]\)和\([mid+1,r]\),分治下去排序,每次合并的代价是区间的长度,所以得到时间复杂度为: \[ T(n)=2T(\frac{n}{2})+O(n) \] 根据\(master\)定理可知时间复杂度为\(\Theta(nlog
一.定义 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.如2431中,21,43,41,31是逆序,逆序数是4. 二.计算方法 逆序数的计算方法主要有直接计算,归并和树状数组三种,下面将一一介绍. 2.1 直接计算 即根据定义用枚举的方法求逆序数.对于数列中的每一个数a[i],遍历数列中的数a[j] (其中j < i),若a[i] < a[j],则逆序数加1,这样就能统计出该数列的逆序数总和. 该方
为什么线段树可以求逆序数? 给一个简单的序列 9 5 3 他的逆序数是3 首先要求一个逆序数有两种方式:可以从头开始往后找比当前元素小的值,也可以从后往前找比当前元素大的值,有几个逆序数就是几. 线段树就是应用从后往前找较大值得个数.(一边更新一边查) 当前个数是 n = 10 元素 9 5 3 9先加入线段树,T[9]+=1:查从T[9]到T[10]比9大的值,没有sum = 0: 5 加入线段树,T[5] += 1,查从T[5]到T[10]比5大的值,有一个9,sum +=1: 3
今天继续学了算法,首先是一个计算数组中的逆序数的算法. 通常,很容易想到的计算办法就是运用两个for循环遍历比较整个数组,当某个数字的下标较大,而值却小于小标比它小的某个位置上的值时,逆序数+1,但是此种算法复杂度较高,随着输入数据规模的增大效率会快速下降(即输入的数组变大了),具体的复杂度计算方法如下:设数组有n个元素,则需要遍历n次,而每一次遍历中要与下标在后面的进行比较,在当次遍历中,其后具有(n-当次遍历的元素的下标)个元素,那么就需要进行n^2/2次操作(后面的元素不需要再与前面的比较
题目传送门 1 /* 2 求逆序数的四种方法 3 */ 1 /* 2 1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]....t[N] 3 它的逆序列个数是N个,如果把t[1]放到t[N]后面,逆序列个数会减少t[1]个,相应会增加N-(t[1]+1)个 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm>
求一个数列的逆序数 逆序对:数列s[1],a[2],a[3]-中的任意两个数s[i],s[j] (i<j),如果s[i]>s[j],那么我们就说这两个数构成了一个逆序对 逆序数:一个数列中逆序对的总数 如数列 3 5 4 8 2 6 9 (5,4)是一个逆序对,同样还有(3,2),(5,2),(4,2)等等 那么如何求得一个数列的逆序数呢? 方法1:一个一个的数 最简单也是最容易想到的方法就是,对于数列中的每一个数s[i],遍历数列中的数s[j](其中j<i),若s[i]<s[j]
1.归并排序求逆序数 http://acm.nyist.net/JudgeOnline/problem.php?pid=117 在归并排序的过程中,比较关键的是通过递归,将两个已经排好序的数组合并,此时,若a[i] > a[j],则i到m之间的数都大于a[j],合并时a[j]插到了a[i]之前,此时也就产生的m-i+1个逆序数,而小于等于的情况并不会产生. 1 #include<stdio.h> 2 #define maxn 1000005 3 int a[maxn],temp[maxn