zoukankan      html  css  js  c++  java
  • [HDOJ1394]Minimum Inversion Number(线段树,逆序数)

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

    题意:一个数的逆序数为inv,然后求这个数列的第一个数后变为最后一个数,过程中逆序数最小的时候的逆序数。

    用线段树,先建立一棵空树,之后向树内插点。在插入之前进行一次统计,求出比这个数大的个数,累计相加。得出当前逆序数。也可用归并排序、树状数组之类的方法。

    之后移动每次的第一个数,可以用二分搜两遍,求出多少个数比它大,多少个数比它小。用当前逆序数加上比它大的数的个数,减去比它小的个数即可求得当前逆序数。

    也可以得到规律:第i个数变成第n-1数的时候,要减去后面比它小的数(tmp[i]个),要加上后面比它大的数(n-tmp[i]+1个)。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <fstream>
     8 #include <cassert>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <bitset>
    12 #include <vector>
    13 #include <deque>
    14 #include <queue>
    15 #include <stack>
    16 #include <ctime>
    17 #include <set>
    18 #include <map>
    19 #include <cmath>
    20 
    21 using namespace std;
    22 
    23 #define lson l, m, rt << 1
    24 #define rson m + 1, r, rt << 1 | 1
    25 const int maxn = 6666;
    26 int num[maxn<<2];
    27 int tmp[maxn];
    28 
    29 void pushUP(int rt) {
    30     num[rt] = num[rt<<1] + num[rt<<1|1];
    31 }
    32 
    33 void build(int l, int r, int rt) {
    34     num[rt] = 0;
    35     if(l == r) {
    36         return;
    37     }
    38     int m = (l + r) >> 1;
    39     build(lson);
    40     build(rson);
    41 }
    42 
    43 void update(int p, int l, int r, int rt) {
    44     if(l == r) {
    45         num[rt]++;
    46         return;
    47     }
    48     int m = (l + r) >> 1;
    49     if(p <= m) {
    50         update(p, lson);
    51     }
    52     else {
    53         update(p, rson);
    54     }
    55     pushUP(rt);
    56 }
    57 
    58 int query(int L, int R, int l, int r, int rt) {
    59     if(L <= l && r <= R) {
    60         return num[rt];
    61     }
    62     int m = (l + r) >> 1;
    63     int cur = 0;
    64     if(L <= m) {
    65         cur += query(L, R, lson);
    66     }
    67     if(R > m) {
    68         cur += query(L, R, rson);
    69     }
    70     return cur;
    71 }
    72 
    73 int main() {
    74     // freopen("in", "r", stdin);
    75     int n;
    76     while(~scanf("%d", &n)) {
    77         build(0, n-1, 1);
    78         int inv = 0;
    79         for(int i = 0; i < n; i++) {
    80             scanf("%d", &tmp[i]);
    81             inv += query(tmp[i], n-1, 0, n-1, 1);
    82             update(tmp[i], 0, n-1, 1);
    83         }
    84         int ans = 0;
    85         for(int i = 0; i < n; i++) {
    86             inv = inv - tmp[i] + n - tmp[i] - 1;
    87             ans = min(ans, inv);
    88         }
    89         printf("%d
    ", ans);
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    每日日报24
    每日日报23
    每日日报22
    链路层:MAC 地址
    应用层:电子邮件
    应用层:HTTP 协议
    应用层:DNS 域名系统
    运输层:TCP 拥塞控制
    运输层:拥塞控制原理
    JAVA学习日记26-0731
  • 原文地址:https://www.cnblogs.com/kirai/p/5194083.html
Copyright © 2011-2022 走看看