zoukankan      html  css  js  c++  java
  • hdu1394(Minimum Inversion Number)线段树

    明知道是线段树,却写不出来,搞了半天,戳,没办法,最后还是得去看题解(有待于提高啊啊),想做道题还是难啊。

    还是先贴题吧

    HDU-1394 Minimum Inversion Number

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 8324    Accepted Submission(s): 5115


    Problem Description
    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

    For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

    a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
    a2, a3, ..., an, a1 (where m = 1)
    a3, a4, ..., an, a1, a2 (where m = 2)
    ...
    an, a1, a2, ..., an-1 (where m = n-1)

    You are asked to write a program to find the minimum inversion number out of the above sequences.
     
    Input
    The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
     
    Output
    For each case, output the minimum inversion number on a single line.
     
    Sample Input
    10
    1 3 6 9 0 8 5 7 4 2
    Sample Output
    16
    思路:依次统计a[i]前面有多少个比它大,求和就是初始化序列的逆序数个数;所有的数都在第一个数之后,那么比第一个数大的个数为n-a[1] - 1,比a[1]小的数就是a[1](关键),每次把第一个数放到最后一个位置时,逆序数增加了n-a[1]-1-a[1]了,明白了这个就好做了。
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <set>
     6 #include <map>
     7 #include <vector>
     8 #include <queue>
     9 #define N 5005
    10 using namespace std;
    11 int a[N];
    12 int segtree[N << 2];
    13 void update(int ll, int rr, int l, int r, int p)
    14 {
    15     if (ll <= l && rr >= r)
    16     {
    17         segtree[p]++;
    18         return;
    19     }
    20     int mid = (l + r) >> 1, pp = p << 1;
    21     if (mid >= rr)
    22         update(ll, rr, l, mid, pp);
    23     else
    24         if (mid < ll)
    25             update(ll, rr, mid + 1, r, pp + 1);
    26         else
    27         {
    28             update(ll, mid, l, mid, pp);
    29             update(mid + 1, rr, mid + 1, r, pp + 1);
    30         }    
    31     segtree[p] = segtree[pp] + segtree[pp + 1];    
    32 } 
    33 int query(int ll, int rr, int l, int r, int p)
    34 {
    35     if (ll <= l && rr >= r)
    36         return segtree[p]++;
    37     int mid = (l + r) >> 1, pp = p << 1;
    38     if (mid >= rr)
    39         query(ll, rr, l, mid, pp);
    40     else
    41         if (mid < ll)
    42             query(ll, rr, mid + 1, r, pp + 1);
    43         else
    44             return query(ll, mid, l, mid, pp) + 
    45             query(mid + 1, rr, mid + 1, r, pp + 1);
    46 }
    47 int main()
    48 {
    49     int n, i, ans, minans;
    50     while (~scanf("%d", &n))
    51     {
    52         memset(segtree, 0, sizeof(segtree));
    53         ans = 0;
    54         for (i = 1; i <= n; i++)
    55         {
    56             scanf("%d", &a[i]);
    57             update(a[i] + 1, a[i] + 1, 1, n, 1);//将所有数加1,除去0,线段树下标从1开始
    58             if (a[i] + 1 < n)//当a[i] = n,不操作 
    59                 ans += query(a[i] + 2, n, 1, n, 1); 
    60         }
    61         minans = ans;
    62         for (i = 1; i < n; i++)
    63         {
    64             ans += n - a[i] * 2 -1;
    65             if (minans > ans)
    66                 minans = ans;
    67         }
    68         printf("%d
    ", minans);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    Linux下暴力破解工具Hydra详解
    Github 安全类Repo收集整理
    Linux下显示IP地理位置信息的小工具-nali
    一次渗透小记
    一步随心,一生无悔
    巧遇"drwxr-xr-x."权限
    mysql以ROOT权限提权方法
    HTTP消息中header头部信息的讲解
    浏览器安全-初学篇
    高并发工具推荐
  • 原文地址:https://www.cnblogs.com/jecyhw/p/3446755.html
Copyright © 2011-2022 走看看