您的位置:首页 > 其它

HDU 5497 Inversion

2015-10-05 17:15 344 查看
Problem Description

You have a sequence {a_1,a_2,...,a_n}{a​1​​,a​2​​,...,a​n​​} 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≤10​5​​,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)a​1​​,a​2​​,...,a​n​​(1≤a​i​​≤n).
The sum of nn in
the test cases will not exceed 2
\times 10^62×10​6​​.

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

树状数组,初始化的时候用循环。。。
#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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: