Minimum Inversion Number

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

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 的 0-n-1 的全排列  你可以进行若干次操作 把第一个数放到最后面 形成一个新的序列(最多n个)问所有序列中逆序对最少的数量。

解析:逆序对很好求 对于每一个数看它前面有多少个比它大的记为sum[ a[i] ] sigmasum[] 就是逆序的数量 每个位置都如此,线段树就是每次查询[a[i],n-1] 的个数;

假如当前序列的逆序对是ans 那么把当前第一个数a[i] 放到最后面 后面对于每个数[0,a[i]) sum[ ] 就会少一次 同样 sum[ a[i] ] = n-1-a[i]

所以 操作之后就是 ans+=n-a[i]+n-1-a[i]。取最大值就好了

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
const int maxn = 1e4+;
const int inf = 0x3f3f3f3f;
const int mod = ;
const double epx = 1e-;
const double pi = acos(-1.0);
//head-----------------------------------------------------------------
int sum[maxn*];
void PushUp(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
}
void build(int l,int r,int rt)
{
if(l==r)
{
sum[rt]=;
return;
}
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
PushUp(rt);
}
void update(int x,int val,int l,int r,int rt)
{
if(l==x&&r==x)
{
sum[rt]+=val;
return;
}
int mid=(l+r)>>;
if(x<=mid)
update(x,val,l,mid,rt<<);
else
update(x,val,mid+,r,rt<<|);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return sum[rt];
}
int mid=(l+r)>>;
int ans=;
if(L<=mid)
ans+=query(L,R,l,mid,rt<<);
if(R>mid)
ans+=query(L,R,mid+,r,rt<<|);
return ans;
}
int a[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
fillchar(sum,);
int ans=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
update(a[i]+,,,n,); //出于方便从1开始
ans+=query(a[i]+,n,,n,);
}
int ret=inf;
for(int i=;i<=n;i++)
{
ans+=n-*a[i]-;
ret=min(ans,ret);
}
printf("%d\n",ret);
}
}

复习一下线段树基础。。

HDU 1394 线段树求逆序对的更多相关文章

  1. hdu 1394 (线段树求逆序数)

    <题目链接> 题意描述: 给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找 ...

  2. 4163 hzwer与逆序对 (codevs + 权值线段树 + 求逆序对)

    题目链接:http://codevs.cn/problem/4163/ 题目:

  3. BNU 2418 Ultra-QuickSort (线段树求逆序对)

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=2418 解题报告:就是给你n个数,然后让你求这个数列的逆序对是多少?题目中n的范围是n & ...

  4. HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少 ...

  5. hdu1394(线段树求逆序对)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 线段树功能:update:单点增减 query:区间求和 分析:如果是0到n-1的排列,那么如果 ...

  6. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  7. poj2299 Ultra-QuickSort(线段树求逆序对)

    Description In this problem, you have to analyze a particular sorting algorithm. The algorithm proce ...

  8. hdu 1394 线段树计算逆序数

    线段树计算逆序数的原理: 用线段树来统计已插入的数的个数(所以要保证最大的那个数不能太大,否则数组都开不了),然后每插入一个数,就查询比插入的数大的个数,累加即可. 这个题还有一个特点就是,题目给的是 ...

  9. hdu 1394(线段树) 最小逆序数

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 给出一列数组,数组里的数都是从0到n-1的,在依次把第一个数放到最后一位的过程中求最小的逆序数 线段树的应 ...

随机推荐

  1. linux环境nginx的安装与使用

    因为公司需要需要安装一系列环境,新手上路第一次配的时候什么也不懂在网上找了半天,觉得这篇不错,我在这里顺便记录一下.(原文:https://www.cnblogs.com/wyd168/p/66365 ...

  2. windows10 下安装、配置、启动mysql

    下载mysql 可以自行去百度 或者 https://dev.mysql.com/downloads/mysql/5.7.html#downloads 解压mysql-5.7.26-winx64.zi ...

  3. 企业自颁布服务器证书的有效性验证(C#为例)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/notjusttech/article/details/72779904 目前根据项目的需要,整理了一 ...

  4. sstable, bigtable,leveldb,cassandra,hbase的lsm基础

    先看懂文献1和2 1. 先了解sstable.SSTable: Sorted String Table [2] [10] WiscKey:  类似myisam, key value分离, 根据ssd优 ...

  5. ★房贷计算器 APP

    一.目的 1. 这是一个蛮有用的小工具 2. 之前看了很多demo,第一次来完全的自己实现一个APP 3. 完成之后提交 App Store 4. 作为Good Coder的提交审核材料 二.排期 周 ...

  6. jwt 登录

    /* eslint-disable */ 'use strict'; const Controller = require('egg').Controller; const jwt = require ...

  7. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...

  8. 【模拟】bzoj1686: [Usaco2005 Open]Waves 波纹

    打完模拟题来庆祝一波:):感觉最近陷入一种“口胡五分钟打题两小时”的巨坑之中…… Description Input     第1行:四个用空格隔开的整数Pj Bi,B2,R. P(1≤P≤5)表示石 ...

  9. R语言基础-data.frame

    data.frame比较像表格,每一列是一个向量,即每列中的元素是同一类型:所有列具有相同的长度. x = 10:1 y = -4:5 q = c("Ha","oh&qu ...

  10. I2C驱动框架(二)

    参考:I2C子系统之I2C bus初始化——I2C_init() 在linux内核启动的时候最先执行的和I2C子系统相关的函数应该是driver/i2c/i2c-core.c文件中的i2c_init( ...