Minimum Inversion Number(线段树)
2015-10-10 16:35
507 查看
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15151 Accepted Submission(s): 9250
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
ZOJ Monthly, January 2003
题意:
给你N个数,要求统计它的所有形式的逆序对的最小值。它的所有形式的意思是,不断将数组开头的第一个数放到数组的最后面。
这题求逆序数的用了我四五个晚上终于A了,一开始参考别人的代码,结果却一直运行不起来。到运行起来了,却答案错误。现在终于将它A了,很高兴。
AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; #define T 5005 int n, a[T],ans; struct node { int l,r,mid; int v; }tree[T<<2]; void PushUp(int rt) { tree[rt].v = tree[rt << 1].v + tree[rt << 1 | 1].v; } void Build(int rt,int L,int R) { tree[rt].l = L; tree[rt].r = R; tree[rt].mid = (L + R) >> 1; tree[rt].v = 0; if (L == R)return; Build(rt<<1,L,tree[rt].mid); Build(rt<<1|1,tree[rt].mid+1,R); } void add(int rt,int pos) { if (tree[rt].l ==pos && tree[rt].r==pos){ tree[rt].v=1; return; } if (pos <= tree[rt].mid){ add(rt<<1,pos); } else { add(rt<<1|1,pos); } PushUp(rt); } void query(int rt,int L,int R) { if (tree[rt].l>=L&&tree[rt].r<=R){ ans+=tree[rt].v; return; } if (R <= tree[rt].mid){ query(rt<<1,L,R); } else if (L > tree[rt].mid){ query(rt<<1|1,L,R); } else { query(rt<<1,L,tree[rt].mid); query(rt<<1|1,tree[rt].mid+1,R); } } int main() { /*freopen("input.txt","r",stdin);*/ int i; while (~scanf("%d", &n)) { ans = 0; Build(1,1,n); for (i = 0; i < n;++i){ scanf("%d",&a[i]); a[i]++; if (a[i]!=n) query(1,a[i]+1,n); add(1,a[i]); } int mi = ans; for (i = 0; i < n;++i){ ans = ans - ((a[i]-1)<<1) + n - 1; mi = min(mi,ans); } printf("%d\n",mi); } return 0; }
相关文章推荐
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 数据结构之Treap详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例
- Java数据结构及算法实例:三角数字
- Java数据结构之简单链表的定义与实现方法示例
- 数据结构之AVL树详解
- qqwry.dat的数据结构图文解释第1/2页
- JavaScript中数据结构与算法(五):经典KMP算法