poj 2299 逆序数
来源:互联网 发布:软件外包公司简介 编辑:程序博客网 时间:2024/06/13 01:05
poj 2299 求逆序数
逆序数的定义:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。
一,利用归并排序求逆序数
利用归并排序求逆序数的原理:利用归并求逆序是指在对子序列s1和s2归并的时候,如果s1[i] > s2[j], 那么子序列s1从i到strlen(s1) 都大于s2[j],也就是构成了逆序,那么逆序数+= strlen(s1) - i + 1;
#include <iostream>#include <algorithm>using namespace std;__int64 change;int arr[505000];//升序void merge(int arr[], int leftPos, int rightPos, int rightEnd) //合并{int *temp = (int*)malloc((rightEnd-leftPos+3)*sizeof(int));int leftEnd = rightPos - 1;int tempPos = 0;int start = leftPos;while(leftPos <= leftEnd && rightPos <= rightEnd){if(arr[leftPos] <= arr[rightPos]){temp[tempPos++] = arr[leftPos++];}else{temp[tempPos++] = arr[rightPos++];change += leftEnd - leftPos + 1; //在归并排序中加上这句代码即可}}while(leftPos <= leftEnd){temp[tempPos++] = arr[leftPos++];}while(rightPos <= rightEnd){temp[tempPos++] = arr[rightPos++];}for(int i=0; i<tempPos; i++){arr[start+i] = temp[i];}free(temp);}void mergeSort(int arr[], int left, int right) //归并排序{if(left < right){int center = (left + right) / 2;mergeSort(arr,left,center);mergeSort(arr,center+1,right);merge(arr,left,center+1,right);}}int main(){int n;while(cin>>n,n){change = 0;for(int i=0; i<n; i++){cin>>arr[i];}mergeSort(arr,0,n-1);cout<<change<<endl;}return 0;}
二,离散化+树状数组
//先离散化,再利用树状数组#include "stdafx.h"#include <iostream>#include <algorithm>using namespace std;const int MAXN = 500010;int sum[MAXN];int num[MAXN];struct Point{int val;int id;bool const operator < (const struct Point& a)const{return val < a.val;}}p[MAXN];int lowbit(int x){return x & (-x);}void update(int x, int val){while(x < MAXN){sum[x] += val;x = x + lowbit(x);}}int getSum(int x){int s = 0;while(x > 0){s += sum[x];x = x - lowbit(x);}return s;}int main(){int n;while(cin>>n,n){memset(sum,0,sizeof(sum));for(int i=1; i<=n; i++){cin>>p[i].val;p[i].id = i;}//离散化,即将 100 20 2000 1000等,转化为 2 1 4 3sort(p+1,p+n+1);for(int i=1; i<=n; i++){num[i] = p[i].id;}__int64 ans = 0;for(int i=n; i>=1; i--) //从后往前操作,具体解释看下一篇树状数组应用{ans += getSum(num[i]);update(num[i],1);}cout<<ans<<endl;}return 0;}
- poj 2299 逆序数
- poj 2299 求逆序数
- Poj 2299:求逆序数
- poj 2299 求逆序数
- poj 2299 逆序数树状数组
- poj 2299树状数组求逆序数
- poj 2299 归并排序求逆序数
- poj 2299 归并求逆序数
- poj-2299-逆序数-归并排序
- POJ 2299 Ultra-QuickSort (求逆序数)
- POJ 2299 快速求逆序数
- POJ 2299 Ultra-QuickSort (逆序数)
- 树状数组 求逆序数 poj 2299
- 树状数组求逆序数--poj 2299
- poj 2299 又是逆序数。。。
- POJ 2299--Ultra-QuickSort【逆序数】
- Poj 2299 Ultra-QuickSort (归排求逆序数)
- poj 2299树状数组求逆序数
- PrepareStatement与Statement之间的区别
- android-导航条
- Oracle 进程结构(Process Structure)
- 两个周的折腾(三)——在线文本编辑器与oracle
- RAC的GES/GCS原理 (转)
- poj 2299 逆序数
- 缓存融合和全局内存服务——RAC概念
- 手把手教你玩转SOCKET模型之重叠I/O篇(上)
- RAC Architecture and Concepts
- 大熊的BLOG
- android-抽屉式界面slidingDrawer
- 鞭长莫及的真正含义新解
- 啄木鸟空间
- Ftp多线程与断点续传