题意:给定一个序列,求逆序对个数,每次可以交换两个数。((nleq 2*10^4) ,(mleq 2*10^3))
直接先处理第一次的答案,然后再考虑交换对答案的贡献。
因为 (n,m)都很小,所以可以直接暴力查询每次改变的量即可。
时间复杂度 (O(nlogn+nm)) 。
yhx的做法:
然后就行了,因为我是口胡,所以再贴一下他的代码。
#include <bits/stdc++.h>
#define sgn(i, j) ((a[i] > a[j]) - (a[i] < a[j])) // sgn(c[i] - c[j])
#define N 20034
using namespace std;
int n, q, i;
int l, r, ans = 0;
int a[N], buf[N], tmp[N];
int MergeSort(int L, int R){ // mergesort[L, R)
if(L + 1 == R) return L;
int M = L + R >> 1;
MergeSort(L, M);
MergeSort(M, R);
int i, j, k = L;
memcpy(tmp + L, buf + L, M - L << 2);
for(i = L, j = M; i < M || j < R; )
if(j >= R || (i < M && tmp[i] <= buf[j]))
buf[k++] = tmp[i++];
else{
buf[k++] = buf[j++];
ans += M - i;
}
return L;
}
int main(){
scanf("%d", &n);
for(i = 1; i <= n; i++)
scanf("%d", a + i);
memcpy(buf + 1, a + 1, n << 2);
MergeSort(1, n + 1);
printf("%d
", ans);
for(scanf("%d", &q); q; q--){
scanf("%d%d", &l, &r);
if(l > r) swap(l, r);
if(a[l] == a[r]){
printf("%d
", ans);
continue;
}
for(i = l; i < r; i++)
ans += sgn(i, l) + sgn(r, i);
swap(a[l], a[r]);
printf("%d
", ans);
}
return 0;
}