zoukankan      html  css  js  c++  java
  • hdu1394 Minimum Inversion Number (线段树求逆序数&&思维)

    题目传送门

    Minimum Inversion Number

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


    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
     
    Author
    CHEN, Gaoli
     
    Source
     
    Recommend
    Ignatius.L   |   We have carefully selected several similar problems for you:  1698 1540 1542 1255 2795 
    题意:给你一个环状数列,比如1234,转一下成2341等等,问你在每次转化的时候,
            形成的数列最小的逆序数是多少?
    题解:先用O(logn)的时间求出原始数列的逆序数,然后我们从上面的转移中可以发现,
            每次形成的新数列都是原数列头一个数被转移到最末的位置,即每次要从之前的逆序数
            先-a[i](失去开头数的逆序数),再+n-1-a[i](在末尾新增的逆序数);最后一直枚举
            下来边求最小值即可
    代码:
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef pair<int,int> PII;
    #define mod 1000000007
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    //head
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int maxn=5005;
    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);
        PushUP(rt);
    }
    void update(int p,int l,int r,int rt)
    {
        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 ret=0;
        int m=(l+r)>>1;
       if(L<=m) ret+=query(L,R,lson);
       if(R>m)  ret+=query(L,R,rson);
       return ret;
    }
    int main()
    {
        int n;
        int a[maxn];
        while(~scanf("%d",&n))
        {
            build(0,n-1,1);
            int ans=0;
           for(int i=0;i<n;i++){
                scanf("%d",&a[i]);
                ans+=query(a[i],n-1,0,n-1,1);
              update(a[i],0,n-1,1);
           }
           int cnt=ans;
           for(int i=0;i<n;i++)
           {
               ans+=n-a[i]-a[i]-1;
               cnt=min(ans,cnt);
           }
           printf("%d
    ",cnt);
        }
        return 0;
    }
     
  • 相关阅读:
    Java实现第九届蓝桥杯螺旋折线
    Java实现第九届蓝桥杯递增三元组
    强大的Mockito测试框架
    搭建eclipse环境下 Nutch+Mysql 二次开发环境
    mysql操作查询结果case when then else end用法举例
    查看mysql数据库及表编码格式
    mysql如何更改character-set-server默认为latin1
    (原创)Linux下MySQL 5.5/5.6的修改字符集编码为UTF8(彻底解决中文乱码问题)
    Ubuntu14连接MySql报错“can't connect to local mysql server through socket '/var/run/mysqld/mysqld.sock'”
    inux下设置mysql数据库字符集utf8
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9911988.html
Copyright © 2011-2022 走看看