hdu 1394 Minimum Inversion Number

hdu 1394 的传送门

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

题目大意:
给你一个n个数的排列,然后可以将第一个元素放到最后一个,求这n个数列的最小的逆序数Min;
解题思路:

它的逆序列个数是N个,如果把t[i]放到t[N]后面,逆序列个数会减少t[i]个,相应会增加N-(t[i]+1)个
如果暴力的话,估计会超时,所以就用线段数搞一下,,注意线段树只是一个工具,!!

上代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=5005;
int num[maxn];
struct
{
    int l, r, num;
} tree[4*maxn];

void build(int root, int l, int r)
{
    tree[root].l=l;
    tree[root].r=r;
    tree[root].num=0;
    if(l == r)
        return;
    int mid=(l + r)>>1;
    build(root<<1, l, mid);
    build(root<<1|1, mid+1, r);
}

void update(int root, int pos)
{
    if(tree[root].l == tree[root].r)
    {
        tree[root].num++;
        return;
    }
    int mid=(tree[root].l+tree[root].r)>>1;
    if(pos<=mid)
        update(root<<1, pos);
    else
        update(root<<1|1, pos);
    tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
}

int query(int root, int L, int R)
{
    if(L <= tree[root].l && R >= tree[root].r)
        return tree[root].num;
    int mid=(tree[root].l+tree[root].r)/2,ret=0;
    if(L <= mid)
        ret += query(2*root, L, R);
    if(R>mid)
        ret+=query(2*root+1, L, R);
    return ret;
}
int main()
{

    int m;
    while(~scanf("%d",&m))
    {
        int sum=0;
        build(1, 0, m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d",&num[i]);
            update(1, num[i]);
            sum+=query(1, num[i]+1, m);
        }
        int ans=sum;
        for(int i=1; i<m; i++)
        {
            sum+=(m-1-num[i])-num[i];
            if(sum<ans)
                ans=sum;
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2025-01-14 06:26:39

hdu 1394 Minimum Inversion Number的相关文章

在线等大神-poi导出后台提示报错,Minimum column number is 0!

问题描述 poi导出后台提示报错,Minimum column number is 0! 今天在用poi做导出的时候遇到一些问题! java.lang.IllegalArgumentException: Minimum column number is 0 at org.apache.poi.ss.util.CellRangeAddressBase.validateColumn(CellRangeAddressBase.java:73) at org.apache.poi.ss.util.Cel

HDOJ(HDU) 1562 Guess the number(水题,枚举就行)

Problem Description Happy new year to everybody! Now, I want you to guess a minimum number x betwwn 1000 and 9999 to let (1) x % a = 0; (2) (x+1) % b = 0; (3) (x+2) % c = 0; and a, b, c are integers between 1 and 100. Given a,b,c, tell me what is the

HDU 1385 Minimum Transport Cost:最短路,打印字典序路径

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1385 题目大意: 有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度. 如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费). 现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和. 求最小花费,如果有多条路经符合,则输出字典序最小的路径. 分析与总结: 1.   这题的关键在于按照字典序输出路径. 假设有 1---

hdu 1385 Minimum Transport Cost

点击打开链接hdu 1385 思路:最短路+SPFA+路径记录+路径字典序比较 分析: 1 题目要求的单源的最短路,所以可以选择任意一种单源最短路来求解 2 题目还要求在路径和相同情况下要字典序小的,那么就要在更新dis数组的时候进行更新路径,如果是dis[i]>tmp,那么直接更新:如果是dis[i] == tmp的情况下,那么就要求出star->i 和 star->x的路径进行比较,然后判断能否更新. 3 注意询问的时候可能问的是同一个点. 代码: #include<iostr

HDU 1394 线段树单点更新求逆序数

题意:给出含有0 ~n-1 N个数组成的序列,有N次操作,每次把第一个数放到数列的最后,问这几次数列操作中最小的逆序数的值. 单点更新就可以,每一输入一个数,先查询有几个比这个数大的,再将这个值插入线段树中. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 5005 struct node { i

树状数组专题【完结】

1 国外的论文点击打开链接 2 我的总结点击打开链接 任何能够造成树状数组下表为0的操作都会使得程序TLE,这是个很重要的地方! 第一题 poj 2299 Ultra-QuickSort 点击打开poj 2299 思路: 离散化+树状数组 分析: 1 题目的意思就是要求逆序数对 2 题目的输入个数有500000的规模但是每个数的最大值为999999999,因此我们需要离散化这些数据 3 对于数据9 1 0 5 4我们离散化成5 2 1 4 3 那么对于输入一个树a[i]我们去求一下它的离散化后的

最短路专题【完结】

第一题 hdu 1317 XYZZY 点击打开hdu 1317 思路: 1 题目的图是一个有向图,并且可能存在环.第一个点的能量值为100,边的权值利用能量大小,例如2点为-60,如果1->2那么value[1][2] = -602 题目明确指出如果是要win的话,那么必须是经过的每条边都要大于0.那么我们只要把那些经过松弛操作后的点大于0的入队即可,小于等于0的点肯定不会出现在最终的路径上.3 如果存在正环的话,那么就有能量值无限大,那么这个时候只要判断这个点能否到达n4 判断是否是有环还是五

java-使用JFreeChart产生图片 后台报错!!!!在线等解答

问题描述 使用JFreeChart产生图片 后台报错!!!!在线等解答 因为框架不让修改web.xml文件,故让src等于后台路径,跪求好的实现方法!!!!还有就是后台报错:java.lang.IllegalStateException: getOutputStream() has already been called for this response,虽然搜了网上解决办法,说是jsp使用对象会调用response.getWriter(),因为这个方法是和response.getOutput

NSCLIENT++可以采集的指标

 Documentation   Information   Commands/Modules   CheckDisk   CheckFileSize   CheckDriveSize   CheckFile   CheckEventLog   CheckSystem   CheckCPU   CheckUpTime   CheckServiceState   CheckProcState   CheckMem   CheckCounter   CheckHelpers   CheckAlway