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.

For a given sequence of numbers a1, a2, …, an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, …, an-1, an (where m = 0 - the initial seqence)
a2, a3, …, an, a1 (where m = 1)
a3, a4, …, an, a1, a2 (where m = 2)

an, a1, a2, …, an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.
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

题目意思:大体上说的是求出n次变换中最小的逆序数的个数,不能暴力去模拟,用线段树做,总结出规律,把第一个数放到后面,整个序列改变的逆序数个数=他前面数的个数-第一个数后面的个数。tql %%%大佬们,我蒟蒻。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#define IL inline
#define x first
#define y second
typedef long long ll;
using namespace std;
const	int N=10010;
int w[N];
int a[N];
int b[N];
struct node{
	int l;
	int r;
	int sum;
}tr[N*4];
void pushup(int u)
{
	tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{
	tr[u]={l,r,0};
	if(l==r)	return;
	int mid=l+r>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(u);
}
void modify(int u,int x,int d)
{
	if(tr[u].l==x&&tr[u].r==x)
	{
		tr[u].sum+=d;
		return ;
	}
	int mid=tr[u].l + tr[u].r>>1;
	if(x<=mid)	modify(u<<1,x,d);
	else		modify(u<<1|1,x,d);
	pushup(u);
}
int query(int u,int l,int r)
{
	if(tr[u].l>=l&&tr[u].r<=r)
	return tr[u].sum;
	int mid=tr[u].l+tr[u].r>>1;
	ll sum=0;
	if(l<=mid)		sum+=query(u<<1,l,r);
	if(r>mid)		sum+=query(u<<1|1,l,r);
	return sum;	
}
ll res;
int main()
{
	int n;
	while(cin>>n)
{memset(tr,0,sizeof tr);
	build(1,1,n);
	
		for(int i=1;i<=n;i++)
	{
		cin>>w[i];
		w[i]++;
	}
	ll cnt=0;
	ll res=1e9;
	for(int i=1;i<=n;i++)
	{
	modify(1,w[i],1);
	cnt+=query(1,w[i]+1,n);	
	}
	res=min(res,cnt);
	for(int i=1;i<=n;i++)
	{
		if(w[i]-1>=1)cnt-=query(1,1,w[i]-1);
	if(w[i]+1<=n)	cnt+=query(1,w[i]+1,n);
		res=min(res,cnt);
	}
	cout<<res<<endl;
		}
    return 0;
}