您的位置:首页 > 产品设计 > UI/UE

POJ--2299 Ultra-QuickSort(离散化 + 求逆序数)

2016-01-28 20:16 645 查看
传送门:Ultra-Quicksort

题意:求一个序列的逆序数。

分析:数据范围太大,需要先离散化处理。所谓离散化,就是缩小数与数之间的间隔,但要保证原来的大小关系不变。

           然后是求逆序数,用归并排序的算法或者树状数组皆可。

-----1. 树状数组求逆序数

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;

//AC 407ms
const int maxn = 500000 + 5;
int a[maxn], c[maxn];
int n;

struct num{
int val, pos;
bool operator<(const num &a) const{
return val < a.val;
}
}b[maxn];

int lowbit(int x)
{
return x & -x;
}
void add(int x)
{
for(int i = x; i <= maxn; i += lowbit(i))
c[i]++;
}
int sum(int x)
{
int s = 0;
for(int i = x; i ; i -= lowbit(i))
s += c[i];
return s;
}

void solve()
{
long long ans = 0;
for(int i = 1; i <= n; ++i)
{
add(a[i]);
ans += i - sum(a[i]);
}
cout << ans << endl;
}

void process()  //离散化处理
{
for(int i = 1; i <= n; ++i)
{
scanf("%d", &b[i].val);
b[i].pos = i;
}
stable_sort(b + 1, b + n + 1);
for(int i = 1; i <= n; ++i)
a[b[i].pos] = i;
}
int main()
{
while(cin >> n && n)
{
process();
memset(c, 0, sizeof(c));
solve();
}
return 0;
}


-----2. 归并求逆序数
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>

using namespace std;

//AC, 516ms
const int maxn = 500000 + 5;
int a[maxn], tmp[maxn];
int n;
long long ans;

struct num{
int val, pos;
bool operator<(const num &a) const{
return val < a.val;
}
}b[maxn];

void Merge(int a[], int tmp[], int left, int mid, int right)
{
int i = left, j = mid + 1;
int k = left;

while(i <= mid && j <= right)
{
if(a[i] < a[j]){
tmp[k++] = a[i++];
}
else{
ans += mid - i + 1;
tmp[k++] = a[j++];
}
}
while(i <= mid)   tmp[k++] = a[i++];
while(j <= right) tmp[k++] = a[j++];

for(i = left; i <= right; ++i)
a[i] = tmp[i];
}

void MSort(int a[], int tmp[], int left, int right)
{
if(left < right)
{
int mid = (left + right) >> 1;
MSort(a, tmp, left, mid);
MSort(a, tmp, mid + 1, right);
Merge(a, tmp, left, mid, right);
}
}

void solve()
{
MSort(a, tmp, 1, n);
cout << ans << endl;
}

void process()
{
for(int i = 1; i <= n; ++i)
{
scanf("%d", &b[i].val);
b[i].pos = i;
}
stable_sort(b + 1, b + n + 1);
for(int i = 1; i <= n; ++i)
a[b[i].pos] = i;
}

int main()
{
while(cin >> n && n)
{
ans = 0;
process();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息