zoukankan      html  css  js  c++  java
  • hdu 1394 Minimum Inversion Number 线段树

    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
     
    求逆序数的最小值
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 const int maxn=5010;
     6 int sum[maxn<<2];
     7 void push_up(int rt)
     8 {
     9     sum[rt]=sum[rt<<1]+sum[rt<<1 | 1];
    10 }
    11 void build(int rt,int first,int end)
    12 {
    13      sum[rt]=0;
    14     if(first==end)
    15         return ;
    16     int mid=(first+end)>>1;
    17     build(rt<<1,first,mid);
    18     build(rt<<1 | 1,mid+1,end);
    19 }
    20 int quary(int rt,int first,int end,int left,int right)
    21 {
    22     if(left<=first && right>=end)
    23         return sum[rt];
    24     int mid=(first+end)>>1;
    25     int ans=0;
    26     if(left<=mid)
    27         ans+=quary(rt<<1,first,mid,left,right);
    28     if(right>mid)
    29         ans+=quary(rt<<1 | 1,mid+1,end,left,right);
    30     return ans;
    31 }
    32 void update(int rt,int first,int end,int a)
    33 {
    34     if(first==end)
    35     {
    36         sum[rt]++;
    37         return ;
    38     }
    39     int mid=(first+end)>>1;
    40     if(a<=mid)
    41         update(rt<<1,first,mid,a);
    42     else
    43         update(rt<<1 | 1,mid+1,end,a);
    44         push_up(rt);
    45 }
    46 int a[maxn];
    47 int main()
    48 {
    49     int n;
    50     while(cin>>n)
    51     {
    52         build(1,0,n-1);
    53         int sum=0;
    54         for(int i=0;i<n;i++)
    55         {
    56              cin>>a[i];
    57              sum+=quary(1,0,n-1,a[i],n-1);
    58              update(1,0,n-1,a[i]);
    59         }
    60         int ans=sum;
    61         for(int i=0;i<n;i++)
    62         {
    63             sum+=n-a[i]-a[i]-1;
    64             ans=min(ans,sum);
    65         }
    66         cout<<ans<<endl;
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    angualr清除定时器
    flex布局常用属性
    将数组分割为几个等长度的子数组(使用slice)
    vue+element搭建的后台管理系统
    世界这么大,我想去看看!!!
    angularJs自定义指令(directive)实现滑块滑动
    适用初学者:vue2.0构建单页应用最佳实战
    笔记本win10安装node的尖酸历程。。。。。。
    js对数组处理(数组里边相同元素提取成map)
    快速搞定用Vue+Webpack搭建前端项目(学习好久了,该写点东西了......)
  • 原文地址:https://www.cnblogs.com/cxbky/p/4887726.html
Copyright © 2011-2022 走看看