zoukankan      html  css  js  c++  java
  • Minimum Inversion Number HDU

    Minimum Inversion Number HDU - 1394
    题意:一个由0..n-1组成的序列,每次可以把队首的元素移到队尾,求形成的序列中的最小逆序数(逆序数定义可以参考百度百科)
    思路:假设有长为10的一个序列,由0-9组成,那么,这个序列的第一位数n的逆序对的个数一定是n个!!!因为,在这个序列后面,比n小的个数一定只有n个。假设已知给出的序列的逆序数位ans,序列位t。如果把t[1]放到t[N]后面,逆序列个数会减少t[1]个,相应会增加N-(t[1]+1)个,么,只需知道原序列的逆序数,就可以通过递推,求出变化后的最小逆序数了
    (转载胡浩dalao的博客!!!)
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 5555;
    int sum[maxn<<2];
    void PushUP(int rt) {
           sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void build(int l,int r,int rt) {
           sum[rt] = 0;
           if (l == r) return ;
           int m = (l + r) >> 1;
           build(lson);
           build(rson);
    }
    void update(int p,int l,int r,int rt) {//节点维护[l,r]区间的点的个数
           if (l == r) {
                  sum[rt] ++;
                  return ;
           }
           int m = (l + r) >> 1;
           if (p <= m) update(p , lson);
           else update(p , rson);
           PushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt) {
           if (L <= l && r <= R) {
                  return sum[rt];
           }
           int m = (l + r) >> 1;
           int ret = 0;
           if (L <= m) ret += query(L , R , lson);
           if (R > m) ret += query(L , R , rson);
           return ret;
    }
    int x[maxn];
    int main() {
           int n;
           while (~scanf("%d",&n)) {
                  build(0 , n - 1 , 1);
                  int ans = 0;
                  for (int i = 0 ; i < n ; i ++) {//求出当前序列的逆序数
                         scanf("%d",&x[i]);
                         ans += query(x[i] , n - 1 , 0 , n - 1 , 1);//查找从x[i]到n-1的数的个数,即是当前的逆序数
                         update(x[i] , 0 , n - 1 , 1);
                  }
                  int ret = ans;
                  for (int i = 0 ; i < n ; i ++) {//递推求出变化的最小逆序数
                         ans += n - x[i] - x[i] - 1;
                         ret = min(ret , ans);
                  }
                  printf("%d
    ",ret);
           }
           return 0;
    }

  • 相关阅读:
    openlayers之标注功能四:聚合标注
    openlayers加载百度地图作为底图坐标偏移的解决办法
    设置bootstrap按钮组选中状态
    openlayers F11全屏显示
    8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码
    IDA使用之旅(一)用IDA查看最简单的sys文件
    IDA使用之旅(三)实践中使用IDA工具
    IDA使用之旅(二)工具及窗口的使用
    正则表达式26英文字母大小写互转
    Ollydbg 中断方法
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9092861.html
Copyright © 2011-2022 走看看