E2. Array Optimization by Deque
思路
每次要插入数值的时候,比较放在开头还是结尾贡献的次数,选择较小的位置。主要问题在于如何快速统计之前已经插入过的数和当前数间的大小关系。我们可以先进行离散化,通过树状数组访问已经插入过的比他小的个数与较大的数,实现快速统计。
代码
点此展开
//Author:Daneii
#include <bits/stdc++.h>
using namespace std;
#define in(x) scanf("%d",&x)
typedef long long ll;
const int N=2e5+10;
int n;
int bits[N];
void add(int x,int val)
{
for(int i=x+1;i<=n;i+=i&-i)
{
bits[i-1]+=val;
}
}
int sum(int x)
{
int ans=0;
for(int i=x;i>0;i-=i&-i) ans+=bits[i-1];
return ans;
}
int main()
{
int _=1;
in(_);
while(_--)
{
in(n);
vector<int> a(n);
vector<int> seg(n);
for(int i=0;i<n;i++)
{
in(a[i]);
bits[i]=0;
seg[i]=a[i];
}
//离散化
sort(seg.begin(),seg.end());
seg.erase(unique(seg.begin(),seg.end()),seg.end());
ll ans=0;
for(int i=0;i<n;i++)
{
int tmp=lower_bound(seg.begin(),seg.end(),a[i])-seg.begin();
add(tmp,1);
ans+=min(sum(tmp),sum(seg.size())-sum(tmp+1));
}
cout<<ans<<endl;
}
return 0;
}