首页 > 代码库 > hdu 1394 Minimum Inversion Number - 树状数组
hdu 1394 Minimum Inversion Number - 树状数组
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
101 3 6 9 0 8 5 7 4 2
Sample Output
16
题目大意 求循环排列最小逆序对数。
老是刷cf,不做暑假作业估计会被教练鄙视,所以还是做做暑假作业。
先用各种方法算出原始序列的逆序对数。
显然你可直接算出把开头的一个数挪到序列后面增加的逆序对数。(后面有多少个比它大减去有多少个比它小)
于是这道题就水完了。
Code
1 /** 2 * hdu 3 * Problem#1394 4 * Accepted 5 * Time: 62ms 6 * Memory: 1680k 7 */ 8 #include <iostream> 9 #include <fstream> 10 #include <sstream> 11 #include <cstdio> 12 #include <ctime> 13 #include <cmath> 14 #include <cctype> 15 #include <cstring> 16 #include <cstdlib> 17 #include <algorithm> 18 #include <map> 19 #include <set> 20 #include <list> 21 #include <stack> 22 #include <queue> 23 #include <vector> 24 #ifndef WIN32 25 #define Auto "%lld" 26 #else 27 #define Auto "%I64d" 28 #endif 29 using namespace std; 30 typedef bool boolean; 31 const signed int inf = (signed)((1u << 31) - 1); 32 const signed long long llf = (signed long long)((1ull << 61) - 1); 33 const double eps = 1e-9; 34 const int binary_limit = 256; 35 #define smin(a, b) a = min(a, b) 36 #define smax(a, b) a = max(a, b) 37 #define max3(a, b, c) max(a, max(b, c)) 38 #define min3(a, b, c) min(a, min(b, c)) 39 template<typename T> 40 inline boolean readInteger(T& u){ 41 char x; 42 int aFlag = 1; 43 while(!isdigit((x = getchar())) && x != ‘-‘ && x != -1); 44 if(x == -1) { 45 ungetc(x, stdin); 46 return false; 47 } 48 if(x == ‘-‘){ 49 x = getchar(); 50 aFlag = -1; 51 } 52 for(u = x - ‘0‘; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - ‘0‘); 53 ungetc(x, stdin); 54 u *= aFlag; 55 return true; 56 } 57 58 #define lowbit(x) ((x) & (-x)) 59 60 typedef class IndexedTree { 61 public: 62 int* lis; 63 int s; 64 IndexedTree() { } 65 IndexedTree(int s):s(s) { 66 lis = new int[(s + 1)]; 67 memset(lis, 0, sizeof(int) * (s + 1)); 68 } 69 70 inline void add(int idx, int val) { 71 for(; idx <= s; idx += lowbit(idx)) 72 lis[idx] += val; 73 } 74 75 inline int getSum(int idx) { 76 int ret = 0; 77 for(; idx; idx -= lowbit(idx)) 78 ret += lis[idx]; 79 return ret; 80 } 81 }IndexedTree; 82 83 int n; 84 int* arr; 85 inline boolean init() { 86 if(!readInteger(n)) return false; 87 arr = new int[(n + 1)]; 88 for(int i = 1; i <= n; i++) 89 readInteger(arr[i]), arr[i] += 1; 90 return true; 91 } 92 93 IndexedTree it; 94 int ans, cmp; 95 inline void solve() { 96 ans = 10000000, cmp = 0; 97 it = IndexedTree(n); 98 for(int i = 1; i <= n; i++) { 99 it.add(arr[i], 1);100 // cout << 1;101 cmp += i - it.getSum(arr[i]);102 }103 ans = cmp;104 for(int i = 1; i < n; i++) {105 cmp -= arr[i] - 1, cmp += n - arr[i];106 smin(ans, cmp);107 }108 printf("%d\n", ans);109 }110 111 inline void clear() {112 delete[] arr;113 delete[] it.lis;114 }115 116 int main() {117 while(init()) {118 solve();119 clear();120 }121 return 0;122 }
hdu 1394 Minimum Inversion Number - 树状数组