题目链接:http://poj.org/problem?id=2299
题目大意:
给n个任意的数字,把他们排序,求最少的交换次数。
题目思路:
开始没想法。后来zjl一说才知道。原来就是求逆序数!每一个数字前面有多少比它小的,这个数字就至少要交换多少次。所以,只需要求这列数字的逆序数就可以!好神奇
还有一个,就是每个数字的范围比较大,开始我还在想开数组貌似放不下,后来zjl说离散化……好吧,果然,我肿么没想到o(╯□╰)o感觉挺自然的想法啊……
剩下的就是原来做过的题目了……甚至比原来做过的还简单
最后一个问题就是,最后的结果应该是long long 的,稍微算一下就知道,最大值(2*10^11)超过了4个字节的整型范围(4 * 10^9),long long 范围是(1*10^19),所以输出要按照long long 输出……这个问题以后一定要注意,判断一下数字的范围!别傻乎乎地就用int……
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cctype> 7 #include <stack> 8 #include <queue> 9 #include <deque> 10 #include <map> 11 #include <set> 12 #include <vector> 13 #include <cmath> 14 #include <algorithm> 15 #define lson l, m, rt<<1 16 #define rson m+1, r, rt<<1|1 17 using namespace std; 18 typedef long long int LL; 19 const int MAXN = 0x7fffffff; 20 const int MINN = -0x7fffffff; 21 const double eps = 1e-9; 22 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 23 {1,1},{1,-1},{-1,-1}}; 24 const int MAX = 500000+10; 25 typedef struct node { 26 int val, index; 27 bool operator < (const node & other) const { 28 return val < other.val; 29 } 30 }node; 31 node in[MAX]; 32 int nu[MAX], a[MAX<<2], n; 33 void solve(); 34 void input() { 35 while (~scanf("%d", &n) && n) { 36 int i; 37 for (i = 0; i < n; ++i) { 38 scanf("%d", &in[i].val); 39 in[i].index = i; 40 } 41 sort(in, in + n); 42 for (i = 0; i < n; ++i) { 43 nu[i] = in[i].index; 44 } 45 solve(); 46 } 47 } 48 void pushup(int rt) { 49 a[rt] = a[rt<<1] + a[rt<<1|1]; 50 } 51 void build(int l, int r, int rt) { 52 if (l == r) {a[rt] = 0; return;} 53 int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); 54 } 55 int query(int L,int R, int l, int r, int rt) { 56 if (L <= l && R >= r) {return a[rt];} 57 int m = (l + r) >> 1, ret = 0; 58 if (L <= m) ret += query(L, R, lson); 59 if (R > m) ret += query(L, R, rson); 60 return ret; 61 } 62 void update(int p, int l, int r, int rt) { 63 if (l == r) { a[rt]++; return;} 64 int m = (l + r) >> 1; 65 if (p <= m) update(p, lson); else update(p,rson); 66 pushup(rt); 67 } 68 void solve() { 69 int i; LL sum = 0; 70 build(0, n-1, 1); 71 for (i = 0; i < n; ++i) { 72 sum += query(nu[i], n-1, 0, n-1, 1); 73 update(nu[i], 0, n-1, 1); 74 } 75 printf("%lld\n", sum); 76 } 77 int main(void){ 78 #ifdef LOCAL 79 freopen("2299.in", "r", stdin); 80 #endif 81 input(); 82 83 return 0; 84 }
复习了一下线段树……