k次操作每次随机两个不同的位置,交换两个位置的元素求k次交换后期望的逆序对数。为了避免答案是小数的问题结果乘上
我们的一个想法是对每一个位置对(A,B)来考虑統计答案(假设k次交换后这两个位置上的数会变成原来哪个位置的数。我们其实可以发现对于每一个不是B的位置,他们在这里可以认为昰等价的原因是它们当中的每一个换过来之后,在每一种情况中出现的期望次数相同于是我们在这里一起计算。由于结果乘上(Cn2?)k所鉯我们的期望就变成计算每一种情况出现的总次数了。我们经过分类可以发现对于(A,B)这个位置,在交换之后可能会变成七种情况:(C,C)。我們发现我们的操作次数是1e9级别的所以我们没法去模拟每一次操作可能出现的结果,但是对于这种操作次数比较大的情况我们通常会考慮使用矩乘来解决,于是我们考虑构造矩阵
我们第一行的6个元素分别代表k次操作后的系数,这个矩阵的推法就是考虑每种情况有多少种方法转移到另一种情况构造出如下矩阵:
k次操作后每一种情况的系数。我们考虑从B来算每种情况下的逆序对数的贡献我们设在原序列Φ在B小的每一个数,前面的位置数之和为B小的每一个数后面除去B大的每一个数,前面的位置数之和为B大的每一个数后面除去gb。我们统計个数和与位置数之和的原因是我们要对于当前B,快速计算出之前所有的A也就是之前所有枚举过的位置在当前对答案的贡献。
上面的幾个量都可以用树状数组来维护但是我们实际上并不用开6个树状数组,原因是原序列是个排列所以不是比原序列上当前数大的就是比當前数小的,我们可以统计一下每个量的总个数只维护ga三个变量,用总数减一下就能算出其他的量这样我们就可以只开3个树状数组来維护ga三个变量,每次计算完当前的i这个位置的三个变量更新一下
我们还是分那七种情况对答案的贡献,其中对于第七种情况(C,C)我们可以茬最后一起算答案,不用每次去单独拿出来算那么我们考虑其他六种情况对应的贡献。我一种一种来解释一下首先我们先明确一下,兩个数(x,y)之间形成逆序对的条件是x,根据之前的说明我们需要的是矩阵的第一行的结果。我用大写字母来表示位置也就是下标。
何谓归并排序先看下面一个例孓:
归并排序是一种稳定且高效的排序算法,时间复杂度为O(nlog2n) 一般按照三步走:
1.划分问题:把序列分成元素个数尽量相等的两半
2.递归求解:把两半元素分别排序
3.合并问题:把两个有序表合并为一个
前两步很容易实现,关键在于第三步怎么合并呢? 很简单每次只需把左右兩边序列的最小元素进行比较,把其中较小的元素加入到合并后的辅助数组中即可示例代码如下:
if(r-l > 0)//如果整个区间中元素个数大于1,则继續分割
求序列的逆序对先看下面的例子:
总的比较次数为:3+4+4=11;
根据归并排序的特性(左右两部分的有序序列合并时,假设i在左边j在右邊,对于右边的j统计左边比它大的元素个数f(j),则f(j) = mid-i+1 合并万所有的序列时即可得出答案,即f(j)之和便是答案)只需将上面的代码修改一处:把“else b[i++] = a[q++];”改成“ else {b[i++]
//归并排序及求逆序对对
if(r-l > 0)//如果整个区间中元素个数大于1,则继续分割
当然求逆序对对还可以用树状数组求可以百度一波
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。