• HDU 1394Minimum Inversion Number(线段树)


    题目大意是说给你一个数组(N个),没戏可以将其首部的k(k<N)个元素移动至尾部,这样总共会形成N个序列

    现在要求这n个序列中逆序对数最少的那一个序列有多少个逆序对

    最初的确是没太多思路,就算知道线段书可以球某一个序列的逆序对数,但是这里要求n次,就没有太多把握了

    而最后的方法其实的确是只用求一次的,由于给出的n个数字是0~n-1的一个排列,所以考虑吧a[0]放到最后一个位置时,那以它作为起点的逆序对数相应的会减少a[0]个(这是因为塔处在地一个位置,所有比它晓得数都会在其后方), 然后考虑a[0]已经被移动到最后一个位置,那么相应的这个序列的逆序对数会增加n-a[0]个

    所以只要在一遍线段书或树状数组求出开始时的逆序对数后,后面的可以由它递推得到

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 1e9
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FOPENIN(IN) freopen(IN, "r", stdin)
    23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
    24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    30 
    31 typedef __int64 LL;
    32 //typedef long long LL;
    33 const int MAXN = 5005;
    34 const int MAXM = 100005;
    35 const double eps = 1e-10;
    36 const LL MOD = 1000000007;
    37 
    38 int c[MAXN], a[MAXN], id[MAXN], N;
    39 
    40 int lowbit(int x)
    41 {
    42     return x & (-x);
    43 }
    44 
    45 void update(int k, int x)
    46 {
    47     while(k <= N)
    48     {
    49         c[k] += x;
    50         k += lowbit(k);
    51     }
    52 }
    53 
    54 int getSum(int k)
    55 {
    56     int sum = 0;
    57     while(k > 0)
    58     {
    59         sum += c[k];
    60         k -= lowbit(k);
    61     }
    62     return sum;
    63 }
    64 
    65 int cmp(int i, int j)
    66 {
    67     return a[i] > a[j];
    68 }
    69 
    70 int getCnt()
    71 {
    72     for(int i=1;i<=N;i++) id[i] = i;
    73     sort(id+1, id + N + 1, cmp);
    74     mem0(c);
    75     int cnt = 0;
    76     for(int i=1;i<=N;i++)
    77     {
    78         cnt += getSum(id[i]);
    79         update(id[i], 1);
    80     }
    81     return cnt;
    82 }
    83 
    84 int main()
    85 {
    86     while(scanf("%d", &N) == 1)
    87     {
    88         for(int i=1;i<=N;i++) scanf("%d", &a[i]);
    89         int ans = getCnt(), x = ans;
    90         for(int i=1;i<N;i++)
    91         {
    92             x = x + N - 2 * a[i] - 1;
    93             ans = MIN(ans, x);
    94         }
    95         printf("%d
    ", ans);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    chrome调试Android webview页面
    Ractive 的 一些认识
    backbone的一些认识
    关于Maven打包(Jar)时文件过滤的正确做法
    网页中实现微信登录(OAuth)的不完整记录
    将项目发布到Maven中央仓库时关于GPG的一些操作日志
    记录一下自己在 eclipse 中使用的 javadoc 模板
    记录一下MySQL的表分区常用操作
    在H5 App中实现自定义Token的注意事项
    再来复习一下Javascript中关于数组和对象的常用方法
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3884639.html
Copyright © 2020-2023  润新知