HDU1394用树状数组求逆序数
来源:互联网 发布:电信运营商数据 编辑:程序博客网 时间:2024/04/30 11:57
题意:一个由0..n-1组成的序列,每次可以把队首的元素移到队尾,求形成的n个序列最小逆序对数目
算法:
由树状数组求逆序对。加入元素i即把以元素i为下标的a[i]值+1,从队尾到队首入队,
每次入队时逆序对数 += getsum(i - 1),即下标比它大的但是值比它小的元素个数。
因为树状数组不能处理下标为0的元素,每个元素进入时+1,相应的其他程序也要相应调整。
求出原始的序列的逆序对个数后每次把最前面的元素移到队尾,逆序对数即为
算法:
由树状数组求逆序对。加入元素i即把以元素i为下标的a[i]值+1,从队尾到队首入队,
每次入队时逆序对数 += getsum(i - 1),即下标比它大的但是值比它小的元素个数。
因为树状数组不能处理下标为0的元素,每个元素进入时+1,相应的其他程序也要相应调整。
求出原始的序列的逆序对个数后每次把最前面的元素移到队尾,逆序对数即为
原逆序对数+比i大的元素个数-比i小的元素个数,因为是0..n,容易直接算出,每次更新min即可。
#include <stdio.h>#define MAXN 10000int c[MAXN],a[MAXN],n;int min(int a,int b){ if (a < b) return a; else return b;}int lowbit(int i){ return i & -i;}void update(int i,int x){ while (i <= n) { c[i] += x; i += lowbit(i); }}int getsum(int x){ int sum = 0; while (x > 0) { sum += c[x]; x -= lowbit(x); } return sum;}int main(){ while (scanf("%d", &n) == 1) { for (int i = 1; i <= n; i++) c[i] = 0; int sum = 0; for (int i = 1; i <= n; i ++) { scanf ("%d", &a[i]); } for (int i = n; i >= 1; i --) { update (a[i] + 1, 1); sum += getsum (a[i]); } int ans = sum; for (int i = 1; i <= n; i++) { sum = sum - a[i] + (n - a[i] - 1); ans = min(ans, sum); } printf("%d\n", ans); } return 0;}
- HDU1394用树状数组求逆序数
- hdu1394 Minimum Inversion Number(树状数组求逆序数)
- HDU1394 Minimum Inversion Number 求逆序数+树状数组
- hdu1394求最小逆序----树状数组解决
- hdu1394求逆序数
- HDU1394 求逆序数
- hdu1394(求逆序数)
- HDU1394用线段树求逆序数
- 找规律 树状数组求逆序对 hdu1394
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- HDU1285基于有向图邻接表的优先队列的拓扑排序
- appface网站
- 生成1-100不重复的随机数
- SQL恢复技巧
- Linux stat函数讲解
- HDU1394用树状数组求逆序数
- XML文件读写操作
- 加入域的时候提示拒绝访问|活动目录域加入域权限委派
- 经常被vs2008的xx.aspx.designer.cs与界面不同步的问题烦恼
- P欺诈,使用Winpcap对数据包进行拦截
- HDU1394用线段树求逆序数
- 工作中的不顺心
- 使用计算总内存大小的方法确定jvm中为对象分配的存储空间大小
- HDU1671用指针实现的字典树