HDU 1394 Minimum Inversion Number(树状数组求逆序数对)

版权声明:欢迎转载,若转载,请标明出处,如有错误,请指点,也欢迎大佬们给出优化方法 https://blog.csdn.net/Charles_Zaqdt/article/details/82793162

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394

        题意是求0到n-1的逆序数对的个数,每次求完一次可以把第一个值放在最后一个位置,问最小的逆序数对的个数是多少。

        我们可以求出第一种逆序数对 然后通过公式推出其他的逆序数对的个数,至于求的过程当模板看吧...


AC代码:

#include <bits/stdc++.h>
#define maxn 5005
using namespace std;
int n,pre[maxn];
map<int,int> ma;

int lowbit(int x){return x & (-x);}

void Update(int x){
  for(int i=x;i<=n;i+=lowbit(i)){
    ma[i] ++;
  }
}

int Query(int x){
  int ans = 0;
  for(int i=x;i>=1;i-=lowbit(i)){
    ans += ma[i];
  }
  return ans;
}

int main()
{
  while(~scanf("%d",&n)){
    ma.clear();
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++){
      scanf("%d",&pre[i]);
      pre[i]++;
    }
    int ans = 0;
    for(int i=1;i<=n;i++){
      Update(pre[i]);
      ans += i - Query(pre[i]);
    }
    int num = 0x3f3f3f3f;
    for(int i=1;i<=n;i++){
      ans = ans + n - (pre[i] - 1) - 1 - (pre[i] - 1);
      if(num > ans) num = ans;
    }
    printf("%d\n",num);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/Charles_Zaqdt/article/details/82793162