HDU 1394 Minimum Inversion Number (数据结构-段树)

HDU 1394 Minimum Inversion Number (数据结构-段树)

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

Minimum Inversion Number

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


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
 

题目大意:

求逆序数。也就是给你一个序列,每次求逆序数,然再把第一个数放到这个序列的末尾,构成新的序列。问你这n个序列的最小的逆序数。

解题思路:

1、对于每一个序列。其原来的逆序数记为 pre , 假设当前把该序列 第一个数 a[0] 移动到尾部,那么新序列的逆序数为 pre-a[i]+(n-a[i]-1)

由于序列中比a[i]大的数有 n-a[i]-1 个。比a[i]小的有 a[i]个。

因此仅仅需求出第一个序列的逆序数,依次能够递推出这n个序列的逆序数,求出最小的就可以

2、求第一个序列的逆序数的方法

(1)暴力算法,据说不会超时

(2)线段树,建 [0,n]这段树。对于数据 a[i] ,先查询 (a[i]+1,n) 这段的值也就是比a[i]大的数的个数也就是 逆序数,然后插入 (a[i],a[i]) 值为1

代码:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=5100;

struct tree{
    int l,r,sum;
}a[maxn*4];

int data[maxn],n,m;

void build(int l,int r,int k){
    a[k].l=l;
    a[k].r=r;
    a[k].sum=0;
    if(l<r){
        int mid=(l+r)/2;
        build(l,mid,2*k);
        build(mid+1,r,2*k+1);
    }
}

void insert(int l,int r,int k,int c){
    if(l<=a[k].l && a[k].r<=r){
        a[k].sum+=c;
    }else{
        int mid=(a[k].l+a[k].r)/2;
        if(r<=mid) insert(l,r,2*k,c);
        else if(l>=mid+1) insert(l,r,2*k+1,c);
        else{
            insert(l,mid,2*k,c);
            insert(mid+1,r,2*k+1,c);
        }
        a[k].sum=a[2*k].sum+a[2*k+1].sum;
    }
}

int query(int l,int r,int k){
    if(l<=a[k].l  && a[k].r<=r){
        return a[k].sum;
    }else{
        int mid=(a[k].l+a[k].r)/2;
        if(r<=mid) return query(l,r,2*k);
        else if(l>=mid+1) return query(l,r,2*k+1);
        else{
            return query(l,mid,2*k) + query(mid+1,r,2*k+1) ;
        }
    }
}

void solve(){
    int ans=0;
    build(1,n,1);
    for(int i=1;i<=n;i++){
        ans+=query(data[i]+1,n,1);
        insert(data[i]+1,data[i]+1,1,1);
        //cout<<data[i]<<" "<<ans<<endl;
    }
    int tmp=ans;
    for(int i=1;i<=n;i++){
        tmp-=data[i];
        tmp+=n-data[i]-1;
        if(tmp<ans) ans=tmp;
    }
    cout<<ans<<endl;
}

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++) scanf("%d",&data[i]);
        solve();
    }
    return 0;
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116730.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql实时同步工具|sqlserver同步工具|常见的数据库同步工具「建议收藏」

    mysql实时同步工具|sqlserver同步工具|常见的数据库同步工具「建议收藏」SyncNavigator是一款功能强大的数据库同步软件,适用于SQLSERVER,MySQL,具有自动/定时同步数据、无人值守、故障自动恢复、同构/异构数据库同步、断点续传和增量同步等功能,支持Windowsxp以上所有操作系统,适用于大容量数据库快速同步。安装包下载地址:https://www.syncnavigator.cn/Setup.zip帮助文档地址:https://www.syncnavigator.cn/Help_zh-CN.chmWeb文档地址:https://www…

    2025年6月29日
    3
  • 数据结构与算法——从零开始学习(一)基础概念篇「建议收藏」

    前言数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合用计算机存储、组织数据的方式。数据结构分别为逻辑结构、(存储)物理结构和数据的运算三个部分。为什么要学数据结构?首先,因为数据结构作为计算机专业的专业基础课程,是计算机考研的必考科目之一,如果打算报考计算机专业的研究生,你必须学好它;其次,数据结构是计算机软考、计算机等级考试等相关考试的必考内容之一,想要顺利通过这些考…

    2022年4月11日
    44
  • ubuntu设置中文输入法_ubuntu如何使用中文输入法

    ubuntu设置中文输入法_ubuntu如何使用中文输入法找到设置 选择区域和语言点击ManageInstalledLanguagees,提示安装的话安装即可4.点击图示内容。5.将Chinese(simplified)勾选上右键点击住,将汉语拖到第一位重启Ubuntu6.在输入源中点击+号,选中里面的汉语,再选中里面的汉语(IntelligentPinyin),添加即可,并将其移动到第一位。在输入源中点击+号,…

    2022年9月26日
    4
  • wing是什么_nativepage原理

    wing是什么_nativepage原理给定 n 本书,编号为 1∼n。在初始状态下,书是任意排列的。在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。我们的目标状态是把书按照 1∼n 的顺序依次排列。求最少需要多少次操作。输入格式第一行包含整数 T,表示共有 T 组测试数据。每组数据包含两行,第一行为整数 n,表示书的数量。第二行为 n 个整数,表示 1∼n 的一种任意排列。同行数之间用空格隔开。输出格式每组数据输出一个最少操作次数。如果最少操作次数大于或等于 5 次,则输出 5 or more。每个

    2022年8月9日
    6
  • 怎样使用 iOS 7 的 AVSpeechSynthesizer 制作有声书(2)

    怎样使用 iOS 7 的 AVSpeechSynthesizer 制作有声书(2)

    2021年11月29日
    40
  • 基于Java swing+mysql+eclipse的【水电费管理系统】

    基于Java swing+mysql+eclipse的【水电费管理系统】本项目为前几天收费帮学妹做的一个项目,Javaswing项目,在工作环境中基本使用不到,但是很多学校把这个当做编程入门的项目来做,故分享出本项目供初学者参考。CSDN9.9赞助下载:https://download.csdn.net/download/weixin_44893902/20545860白嫖:加QQ68872185一、效果演示主要功能:普通用户:用户用水用电查询(根据时间查询、导出Excel)管理员用户:用户信息管理>>平台用户信息查询(修改信.

    2022年6月17日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号