For a sequence t1...nt_{1...n}t1...n, we define the weight of it is the number of pairs (i,j)(i,j)(i,j) satisfy i<ji<ji<j and ti>tjt_i>t_jti>tj.
Now give you a permutation a1...na_{1...n}a1...n, you need to choose a sequence b1...nb_{1...n}b1...n satisfies bi∈{0,1}b_i\in \{0,1\}bi∈{0,1} to minimize the weight of sequence c1...nc_{1...n}c1...n which satisfies ci=ai+bic_i=a_i+b_ici=ai+bi.
输入描述:
The first line has one integer nnn. The second line has nnn integers a1...na_{1...n}a1...n. It's guaranteed that aia_iai is a permutation of {1,2...n}\{1,2...n\}{1,2...n} 1≤n≤2×1051\leq n\leq 2\times 10^51≤n≤2×105
输出描述:
Output the minimum weight of c1...nc_{1...n}c1...n you can get.
示例1
输入
5 4 3 2 5 1
输出
5
逆序对
1.与序有关,肯定有排序,快排排除,直接归并排序
2.当何时才能使对数少呢?不一样大为对,那么一样大就不是对了,这样就满足使对最少
3.归并也是递归记得还原,扫尾,加入原数组(将临时数组的值赋给原数组)
#include <iostream>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int n,b[N];
int a[N],tmp[N];
ll merge(int l,int r)
{
if(l>=r)
{
return 0;
}
int mid=l+r>>1;
ll res=merge(l,mid)+merge(mid+1,r);
//归并过程
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)//对儿只需要记录一端个数即是全部
{
if(a[i]<=a[j])
{
tmp[k++]=a[i++];
}
else
{
tmp[k++]=a[j++];
res+=mid-i+1;
}
}
//扫尾
while(i<=mid) tmp[k++]=a[i++];
while(j<=r) tmp[k++]=a[j++];
//物归原主
for(int i=l,j=0;i<=r;i++,j++)//递归只到r,就是不管分多小,都是能由两个小的数组组成
{
a[i]=tmp[j];//cout<<a[i]<<" ";//仅仅让开始的a有顺序
}//cout<<endl;
return res;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
//b[a[0]]++;
for(int i=0;i<n;i++)
{
if(b[a[i]+1]!=0)
{
a[i]++;
}
else
{
b[a[i]]++;
}
}
cout<<merge(0,n-1)<<endl;
return 0;
}