E2. Array Optimization by Deque
题目入口
思路
贪心+树状数组
在每次加入一个数时比较加在头和尾时新增逆序对数即可,利用树状数组维护即可,由于求逆序对只需要知道数字比当前数大的有几个,即只需要知道他们之间的相对关系,因此首先将数组离散化。
离散化模板
for(int i=1;i<=n;i++)
{
cin>>a1[i];
a2[i]=a1[i];
}
sort(a1+1,a1+n+1);
int len=unique(a1+1,a1+n+1)-a1-1;
for(int i=1;i<=n;i++)
a2[i]=lower_bound(a1+1,a1+1+len,a2[i])-a1;
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int t,n;
int tree[N];
int a1[N],a2[N];
int lowbit(int x)
{
return x&-x;
}
void add(int pos,int x)
{
while(pos<=n)
{
tree[pos]+=x;
pos+=lowbit(pos);
}
}
int cal(int pos)
{
int res=0;
while(pos>=1)
{
res+=tree[pos];
pos-=lowbit(pos);
}
return res;
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++) tree[i]=0;
for(int i=1;i<=n;i++)
{
cin>>a1[i];
a2[i]=a1[i];
}
sort(a1+1,a1+n+1);
int len=unique(a1+1,a1+n+1)-a1-1;
for(int i=1;i<=n;i++)
a2[i]=lower_bound(a1+1,a1+1+len,a2[i])-a1;
int cnt=0;
int res=0;
for(int i=1;i<=n;i++)
{
int tmp=a2[i];
add(tmp,1);
int check1=cal(n)-cal(tmp);//加在尾
int check2=cal(tmp-1);//加在头
res+=min(check1,check2);
}
cout<<res<<endl;
}
return 0;
}