Problem Description
You have a sequence {a_1,a_2,...,a_n}{a1,a2,...,an} and you can delete a contiguous subsequence of length mm. So what is the minimum number of inversions after the deletion.
Input
There are multiple test cases. The first line of input contains an integer TT, indicating the number of test cases. For each test case:
The first line contains two integers n, m (1 \le n \le 10^5, 1 \le m < n)n,m(1≤n≤105,1≤m<n) - the length of the seuqence. The second line contains nn integers a_1,a_2,...,a_n (1 \le a_i \le n)a1,a2,...,an(1≤ai≤n).
The sum of nn in the test cases will not exceed 2 \times 10^62×106.
Output
For each test case, output the minimum number of inversions.
Sample Input
2 3 1 1 2 3 4 2 4 1 3 2
Sample Output
01
树状数组,初始化的时候用循环。。。
#include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<iostream> using namespace std; typedef long long LL; const int maxn = 300005; const LL base = 1e9 + 7; const int low(int x){ return x&-x; } int T, n, m, a[maxn], f[2][maxn]; LL ans; void insert(int x, int y, int z) { for (int i = y; i <= n; i += low(i)) f[x][i] += z; } int get(int x, int y) { int tot = 0; for (int i = y; i; i -= low(i)) tot += f[x][i]; return tot; } int main() { cin >> T; while (T--) { scanf("%d%d", &n, &m); ans = n; ans = ans*(ans - 1) >> 1; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); f[0][i] = f[1][i] = 0; } LL now = 0; for (int i = m + 1; i <= n; i++) { now += i - m - 1 - get(1, a[i]); insert(1, a[i], 1); } ans = min(ans, now); for (int i = 1; i <= n - m; i++) { insert(1, a[i + m], -1); now -= get(1, a[i + m] - 1) - get(0, a[i + m]); now += get(1, a[i] - 1) - get(0, a[i]); insert(0, a[i], 1); ans = min(ans, now); } printf("%I64d\n", ans); } return 0; }