Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25122 Accepted Submission(s): 14831 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. Input The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1. Output For each case, output the minimum inversion number on a single line. Sample Input 10 1 3 6 9 0 8 5 7 4 2 Sample Output 16 Author CHEN, Gaoli Source Recommend Ignatius.L | We have carefully selected several similar problems for you: 1698 1540 1542 1255 1754 |
代码参考自:https://blog.csdn.net/hellohelloC/article/details/47769657
和:https://blog.csdn.net/u013480600/article/details/22004853
感谢两位大佬!!
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=50000+5;
int sum[maxn*4];
int a[maxn];
void pushup(int x)
{
sum[x]=sum[x*2]+sum[x*2+1];
}
void build(int i,int l,int r)
{
if(l==r)
{
scanf("%d",&sum[i]);
return ;
}
int m=(r+l)/2;
build(i*2,l,m);
build(i*2+1,m+1,r);
pushup(i);
}
void update(int p,int i,int l,int r)
{
if(l==r)
{
sum[i]++;
return ;
}
int m=(l+r)/2;
if(p<=m)update(p,i*2,l,m);
else update(p,i*2+1,m+1,r);
pushup(i);
}
int query(int L,int R,int i,int l,int r)
{
if(L<=l&&r<=R)
{
return sum[i];
}
int m=(r+l)/2;
int res=0;
if(L<=m) res+=query(L,R,i*2,l,m);
if(m<R) res+=query(L,R,i*2+1,m+1,r);
return res;
}
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
int ans=0;
memset(sum,0,sizeof(sum));//也可以在此处选择建树,一样的。。。
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]++;
ans += query(a[i]+1,n,1,1,n);
update(a[i],1,1,n);
}
int min_num=ans;
for(int i=1;i<n;i++)
{
ans = ans+n+1-2*a[i];
min_num=min(min_num , ans);
}
printf("%d\n",min_num);
}
return 0;
}