Problem Description
You have a sequence
{a1,a2,...,an}
and you can delete a contiguous subsequence of length
m
. 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
T
, indicating the number of test cases. For each test case:
The first line contains two integers n,m(1≤n≤105,1≤m<n) - the length of the seuqence. The second line contains n integers a1,a2,...,an(1≤ai≤n) .
The sum of n in the test cases will not exceed 2×106 .
The first line contains two integers n,m(1≤n≤105,1≤m<n) - the length of the seuqence. The second line contains n integers a1,a2,...,an(1≤ai≤n) .
The sum of n in the test cases will not exceed 2×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
0 1
Source
利用两个树状数组维护一个前缀和一个后缀即可,开始写的两份代码写搓了各种TLE,无奈只好换种思路重写代码。
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100010;
const ll inf = (1LL<<50) + 10;
struct Bit {
int n;
int tree[maxn];
void zero() {
memset(tree, 0, sizeof(tree));
}
inline int lowbit(int x) {
return x & (-x);
}
inline void update(int p, int c) {
for(int i = p; i <= n; i += lowbit(i)) {
tree[i] += c;
}
return ;
}
inline int getsum(int p) {
int ans = 0;
for(int i = p; i > 0; i -= lowbit(i)) {
ans += tree[i];
}
return ans;
}
}bit1, bit2;
inline int read() {
int c, x;
while(c = getchar(), !isdigit(c));
x = c - '0';
while(c = getchar(), isdigit(c)) x = x * 10 + c - '0';
return x;
}
int arr[maxn];
int main() {
//freopen("aa.in", "r", stdin);
int T, n, m;
T = read();
while(T--) {
n = read();
m = read();
for(int i = 1; i <= n; ++i) {
arr[i] = read();
}
bit1.n = n; bit1.zero();
bit2.n = n; bit2.zero();
ll sum1 = 0, sum2 = 0, sum3 = 0;
for(int i = n; i > m; --i) {
sum2 += bit2.getsum(arr[i] - 1);
bit2.update(arr[i], 1);
}
ll ans = inf;
for(int i = 1; i + m - 1 <= n; ++i) {
ans = min(ans, sum1 + sum2 + sum3);
if(i + m <= n) {
sum3 -= (bit1.getsum(n) - bit1.getsum(arr[i+m]));
sum2 -= bit2.getsum(arr[i+m] - 1);
bit2.update(arr[i+m], -1);
}
sum3 += bit2.getsum(arr[i] - 1);
sum1 += (bit1.getsum(n) - bit1.getsum(arr[i]));
bit1.update(arr[i], 1);
}
printf("%I64d\n", ans);
}
return 0;
}
/*
const int maxn = 100010;
typedef long long ll;
const ll inf = (1LL<<50) + 10;
int arr[maxn];
ll tree[maxn];
int T, n, m;
int lowbit(int x) {
return x & (-x);
}
void update(int x, int c) {
for(int i = x; i <= n; i += lowbit(i)) {
tree[i] += c;
}
return ;
}
ll getsum(int x) {
if(x == 0) return 0;
ll ans = 0;
for(int i = x; i > 0; i -= lowbit(i)) {
ans += tree[i];
}
return ans;
}
int dp1[maxn], dp2[maxn], dp3[maxn];
int main() {
//freopen("aa.in", "r", stdin);
ll sum;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%d", &arr[i]);
}
sum = 0;
memset(tree, 0, sizeof(tree));
memset(dp1, 0, sizeof(dp1));
for(int i = 1; i <= n; ++i) {
dp1[i] = dp1[i-1] + (getsum(n) - getsum(arr[i]));
update(arr[i], 1);
}
sum = dp1[n];
memset(tree, 0, sizeof(tree));
memset(dp2, 0, sizeof(dp2));
for(int i = n; i >= 1; --i) {
dp2[i] = dp2[i+1] + getsum(arr[i] - 1);
update(arr[i], 1);
}
memset(dp3, 0, sizeof(dp3));
memset(tree, 0, sizeof(tree));
for(int i = 1; i <= n; ++i) {
if(i <= m) {
dp3[i] = dp3[i-1] + (getsum(n) - getsum(arr[i]));
update(arr[i], 1);
} else {
update(arr[i-m], -1);
dp3[i] = dp3[i-1] - getsum(arr[i-m] - 1);
dp3[i] += (getsum(n) - getsum(arr[i]));
update(arr[i], 1);
}
}
ll ans = inf;
for(int i = m; i <= n; ++i) {
ll t = 0;
t += dp1[i] - dp1[i-m];
t += dp2[i-m+1] - dp2[i+1];
t -= dp3[i];
ans = min(ans, sum - t);
}
printf("%I64d\n", ans);
}
return 0;
}
*/
/*
const int maxn = 100010;
typedef long long ll;
const ll inf = (1LL<<50) + 10;
int arr[maxn];
int tarr[maxn];
ll tree[maxn];
int T, n, m, tn;
int lowbit(int x) {
return x & (-x);
}
void update(int x, int c) {
for(int i = x; i <= tn; i += lowbit(i)) {
tree[i] += c;
}
return ;
}
ll getsum(int x) {
ll ans = 0;
for(int i = x; i > 0; i -= lowbit(i)) {
ans += tree[i];
}
return ans;
}
inline int read() {
int c, x;
while(c = getchar(), !isdigit(c));
x = c - '0';
while(c = getchar(), isdigit(c)) x = x * 10 + c - '0';
return x;
}
int bsearch(int x) {
int l = 1, r = tn, mid;
while(l <= r) {
mid = (l + r) / 2;
if(tarr[mid] == x) {
return mid;
} else if(tarr[mid] < x) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return -1;
}
int dp1[maxn], dp2[maxn], dp3[maxn];
int main() {
//freopen("aa.in", "r", stdin);
ll sum;
T = read();
while(T--) {
n = read();
m = read();
for(int i = 1; i <= n; ++i) {
arr[i] = read();
tarr[i] = arr[i];
}
sort(tarr + 1, tarr + n + 1);
tn = unique(tarr + 1, tarr + n + 1) - tarr - 1;
for(int i = 1; i <= n; ++i) {
arr[i] = bsearch(arr[i]);
}
sum = 0;
memset(tree, 0, sizeof(tree));
memset(dp1, 0, sizeof(dp1));
for(int i = 1; i <= n; ++i) {
dp1[i] = dp1[i-1] + (getsum(tn) - getsum(arr[i]));
update(arr[i], 1);
}
sum = dp1[n];
memset(tree, 0, sizeof(tree));
memset(dp2, 0, sizeof(dp2));
for(int i = n; i >= 1; --i) {
dp2[i] = dp2[i+1] + getsum(arr[i] - 1);
update(arr[i], 1);
}
memset(dp3, 0, sizeof(dp3));
memset(tree, 0, sizeof(tree));
for(int i = 1; i <= n; ++i) {
if(i <= m) {
dp3[i] = dp3[i-1] + (getsum(tn) - getsum(arr[i]));
update(arr[i], 1);
} else {
update(arr[i-m], -1);
dp3[i] = dp3[i-1] - getsum(arr[i-m] - 1);
dp3[i] += (getsum(tn) - getsum(arr[i]));
update(arr[i], 1);
}
}
ll ans = inf;
for(int i = m; i <= n; ++i) {
ll t = 0;
t += dp1[i] - dp1[i-m];
t += dp2[i-m+1] - dp2[i+1];
t -= dp3[i];
ans = min(ans, sum - t);
}
printf("%I64d\n", ans);
}
return 0;
}
*/