for(int i=l; i<=r; i++){ f[i]=a[i]; if(a[i].id<=mid) upd(a[i].m, 1); else{ f[i].rk+=sum(a[i].m); } } for(int i=l; i<=r; i++) if(a[i].id<=mid) upd(a[i].m, -1); }这段代码什么意思?
时间: 2024-04-28 10:20:25 浏览: 96
JS for循环中i++ 和 ++i的区别介绍
这段代码是归并排序中实现逆序对统计的部分。
首先将排好序的左半部分`f[l...mid]`复制到数组`a[l...mid]`中,同时对于左半部分的每一个元素,调用`upd`函数进行统计。`a[i].id`表示`a[i]`在原始数组中的下标,`a[i].m`表示右半部分中比`a[i]`小的元素的个数。因此,如果`a[i].id<=mid`,说明`a[i]`属于左半部分,将`a[i].m`插入树状数组中并加一;否则,说明`a[i]`属于右半部分,其逆序对数应该加上右半部分中比它小的元素的个数,即`sum(a[i].m)`。
接下来,将排好序的右半部分`f[mid+1...r]`复制到数组`a[mid+1...r]`中,同时对于左半部分的每一个元素,调用`upd`函数进行统计。这里的统计是为了防止右半部分中的元素被重复计算逆序对。
最后,将树状数组中所有`a[i].m`的值全部清零,以便下一轮统计逆序对。
整个过程可以通过树状数组实现,时间复杂度为$O(n\log n)$。
阅读全文