ZOJ Monthly, June 2018 - J Good Permutation

点击打开链接

题意:

给你一个数列。

问你交换成特殊逆序对所需要的次数。


特殊逆序对:1 2 3 4 5、5 1 2 3 4、4 5 1 2 3、3 4 5 1 2 ……


POINT:

先算出1 2 3 4 5 正常的逆序对所需要的次数。

然后for循环更新。


#include <iostream>
#include <stdio.h>
using namespace std;
const int N = 1e5+55;
#define LL long long
int pos[N];
int num[N];
int n;

void add(int x,int p)
{
	for(int i=x;i<=n;i+=i&-i)
		num[i]+=p;
}

int sum(int x)
{
	int ans=0;
	for(int i=x;i>=1;i-=i&-i)
		ans+=num[i];
	return ans;
}


int main()
{
	int T;
	while(~scanf("%d",&T)){
		while(T--){
			scanf("%d",&n);
			for(int i=1;i<=n;i++){
				int x;
				scanf("%d",&x);
				pos[x]=i;
				add(i,1);
			}
			LL ans=0;
			for(int i=1;i<=n;i++){
				add(pos[i],-1);
				ans+=(LL)sum(pos[i]);
			}
			LL now = ans;
			for(int i=1;i<n;i++){
				now=now-(pos[i]-1)+n-pos[i];
				ans=min(ans,now);
			}
			printf("%lld\n",ans);


		}
	}

}

猜你喜欢

转载自blog.csdn.net/mr_treeeee/article/details/80976129