归并排序大家都会写,分治->选择较小值->移过去->搬回来。
注意一下最后一步,就是把tmp从0开始搬到arr中它该在的位置(也就是从l到r)
然后求逆序对我想不通了~ /(ㄒoㄒ)/~~
为什么要加两次啊!那不就重复了吗!
先丢个模板——
不懂就问,然鹅好像大家都没有我这样的问题,好像还有人直接写
merge_sort(arr, l, mid) , merge_sort(arr, mid + 1, r);
cnt += (mid - i + 1);
//然后最后去打印cnt
小数没问题但是大数就会出问题啊!还是要加两边,为什么呢!
来看些个栗子——
位置发生改变在合并5 6 1这一步,这一步cnt += 2,也就是2
然后arr变成了2 3 4 1 5 6,即将进行最后一步,左序列为2 3 4,右序列为1 5 6,2 3 4都>1所以cnt+=3,也就是5,没毛病!
还不死心,再来看一个例子——
为什么不会重复加呢?
因为每一个分支的cnt都是以它以下的分支为基础加起的,而最底层是从0来的,每一次+=都是比较了第二个序列中指针所指元素比第一个序列中指针所指元素小才会+=,就像那个(0,7)中,2贡献了3,3贡献了3,6贡献了3,79贡献了1,这是累加的,而不是直接赋值,最后,每一个结点都需要左右分支相加才是左右分别的逆序对之和,然后再对左右分别有序,整个无序的数组做merge,又是累加的关系,所以继续+=。
啊!诗乃乃太帅了!然鹅我太菜了!一个归并研究了一上午,但是模板不是光背就行的,还是要搞懂的,不搞懂就背全tmd知识盲区。楼上好吵啊,快点修好吧,孩子顶不住了~