设为首页 加入收藏

TOP

HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
2015-07-20 17:59:21 来源: 作者: 【 】 浏览:2
Tags:HDU 1394 Minimum Inversion Number 线段 最小 序数

HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

ACM

题目地址:HDU 1394 Minimum Inversion Number

题意:
给一个序列由[1,N]构成,可以通过旋转把第一个移动到最后一个。
问旋转后最小的逆序数对。

分析:
注意,序列是由[1,N]构成的,我们模拟下旋转,总的逆序数对会有规律的变化。
求出初始的逆序数对再循环一遍就行了。

至于求逆序数对,我以前用归并排序解过这道题:点这里。
不过由于数据范围是5000,所以完全可以用线段树或树状数组来做:求某个数的作为逆序数对的后面部分的对数,可以在前面的数中查询小于这个数的数的个数。
直接在线一边加一边查就行了,复杂度为O(nlogn)。

不过老实说,这题的单个数没有太大,不然线段树和树状数组都开不下的。所以求逆序数对的最佳算法应该是归并排序解。

代码:

/*
*  Author:      illuz 
  
   
*  Blog:        http://blog.csdn.net/hcbbt
*  File:        1394_segment_tree.cpp
*  Create Date: 2014-08-05 10:08:42
*  Descripton:  segment tree 
*/

#include 
   
     #include 
    
      #include 
     
       #include 
      
        using namespace std; #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define lson(x) ((x) << 1) #define rson(x) ((x) << 1 | 1) typedef long long ll; const int N = 5010; const int ROOT = 1; // below is sement point updated struct seg { ll w; }; struct segment_tree { seg node[N << 2]; void update(int pos) { node[pos].w = node[lson(pos)].w + node[rson(pos)].w; } void build(int l, int r, int pos) { if (l == r) { node[pos].w = 0; return; } int m = (l + r) >> 1; build(l, m, lson(pos)); build(m + 1, r, rson(pos)); update(pos); } // add the point x with y void modify(int l, int r, int pos, int x, ll y) { if (l == r) { node[pos].w += y; return; } int m = (l + r) >> 1; if (x <= m) modify(l, m, lson(pos), x, y); else modify(m + 1, r, rson(pos), x, y); update(pos); } // query the segment [x, y] ll query(int l, int r, int pos, int x, int y) { if (x <= l && r <= y) return node[pos].w; int m = (l + r) >> 1; ll res = 0; if (x <= m) res += query(l, m, lson(pos), x, y); if (y > m) res += query(m + 1, r, rson(pos), x, y); return res; } // remove the point that the sum of [0, it] is x, return its id int remove(int l, int r, int pos, ll x) { if (l == r) { node[pos].w = 0; return l; } int m = (l + r) >> 1; int res; if (x < node[lson(pos)].w) res = remove(l, m, lson(pos), x); else res = remove(m + 1, r, rson(pos), x - node[lson(pos)].w); update(pos); return res; } } sgm; int n, a[N], b[N], t, sum, mmin; int main() { while (~scanf("%d", &n)) { sgm.build(1, n, ROOT); sum = 0; repf (i, 1, n) scanf("%d", &a[i]); for (int i = n; i >= 1; i--) { b[i] = sgm.query(1, n, ROOT, 1, a[i] + 1); sum += b[i]; sgm.modify(1, n, ROOT, a[i] + 1, 1); } mmin = sum; repf (i, 1, n) { sum = sum - a[i] + (n - 1 - a[i]); mmin = min(mmin, sum); } cout << mmin << endl; } return 0; }
      
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 2827 Buy Tickets(排队问题.. 下一篇hdu 1285 确定比赛排名(拓扑排序..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: