用两个树状数组维护前缀后缀的值即可,必须离散化,否则TLE
参考代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
using namespace std;
typedef long long LL;
const LL LINF = (1LL <<63);
const int INF = 1 << 31;
const int NS = 100010;
const int MS = 19;
const LL MOD = 1000000007;
struct BIT{
int len;
int c[NS];
int lowbit(int x)
{
return (x & (-x));
}
void init(int _len)
{
len = _len;
memset(c, 0, sizeof(c));
}
LL sum(int x)
{
LL ret=0;
while(x > 0)
{
ret += c[x];
x -= lowbit(x);
}
return ret;
}
LL sum(int l, int r)
{
LL ret=sum(r);
if(l > 0)
{
ret -= sum(l - 1);
}
return ret;
}
void add(int x, int value)
{
while(x <= len)
{
c[x] += value;
x += lowbit(x);
}
}
}suf, pre;
int n,m;
int a[NS];
int shine[NS];
map<LL, LL> mp;
int main()
{
//#ifndef ONLINE_JUDGE
// freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
//#endif
int T;
scanf("%d", &T);
// cin >> T;
while(T--)
{
scanf("%d %d", &n, &m);
// cin >> n;
for(int i = 1; i <= n; i++)
{
// cin >> a[i];
scanf("%d", &a[i]);
shine[i - 1] = a[i];
}
sort(shine, shine + n);
int num = unique(shine, shine + n) - shine;
for(int i = 1; i <= n; i++)
{
a[i] = lower_bound(shine, shine + num,a[i]) - shine + 1;
}
LL presum = 0;
LL sufsum = 0;
pre.init(num);
suf.init(num);
for(int i = n; i > m; i--)
{
int v = a[i];
sufsum += suf.sum(v - 1);
suf.add(v, 1);
}
LL minv = presum + sufsum;
// cout<<"i = "<<0<<" min = "<<minv<<" presum = "<<presum<<" sufsum = "<<sufsum<<endl;
for(int i = 1; i + m <= n; i++)
{
int v = a[i];
presum += pre.sum(v + 1, num);
presum += suf.sum(1, v - 1);
pre.add(v, 1);
v = a[i + m];
sufsum -= suf.sum(1, v - 1);
sufsum -= pre.sum(v + 1, num);
suf.add(v, -1);
minv = min(minv, presum + sufsum);
// cout<<"i = "<<i<<" min = "<<minv<<" presum = "<<presum<<" sufsum = "<<sufsum<<endl;
}
printf("%I64d\n", minv);
// cout<<minv<<endl;
}
return 0;
}