逆序数的题目还是用树状数组写比较好
先把原序列逆序数求出来。
按题意模拟一下求出最小的逆序。
接下来就是推一下
按题目意思
n 个数 如果a 是第一个元素 那么小于a 的有a 个 (题目给的数据从0 开始)
当a 放到最后 n - 1元素 逆序数 -1 。
a 前面比a 大的元素有 n - a - 1
那么a 的逆序数就是 n - a - 1
所以 a的逆序数s = a * -1 + n - a - 1
就是进行一次操作的 数列的逆序数在加上之前的
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int const MAXN = 5010; int c[MAXN+10],a[MAXN]; inline int Min(int a,int b){ return a<b?a:b; } int LowBit(int x){ return x & (-x); } void Add(int x,int d){ while(x<= MAXN){ c[x] += d; x += LowBit(x); } } int Sum(int x){ int ret = 0; while(x > 0){ ret += c[x]; x -= LowBit(x); } return ret; } int main(){ int n; while(~scanf("%d",&n)){ memset(c,0,sizeof(c)); int sum = 0; for(int i= 1;i <= n;i++){ scanf("%d",&a[i]); Add(a[i] + 1,1); sum += i - Sum(a[i] + 1); //树状数组不能有0 否则会跪 } int cnt = sum; for(int i = 1;i <= n;i++){ sum += n - 2 * a[i] - 1; cnt = Min(cnt,sum); } printf("%d\n",cnt); } return 0; }