poj

来源:互联网 发布:etf套利交易软件 编辑:程序博客网 时间:2024/06/05 11:53


https://vjudge.net/problem/poj-1804


这题也可以用树状数组来做的;想到归并排序求逆序对,也是一种方法,随便说说归并排序:


归并排序是把要排序的数组分成两个部分进行排序,然后将两个部分进行归并,然后在合并的时候因为两个部分都是有序的,所以当a[i] > a[j]的时候,因为i后面的数都不小于a[i],所以后面的数自然也大于a[j],所以加上的是mid - i + 1的逆序对;


#include<iostream>#include<cstdio>using namespace std;const int maxn = 1000 + 10;int a[maxn];int ans;void merge(int l,int r){int mid = (l + r) >> 1;int i = l;int j = mid + 1;int temp[maxn];int k = l;while(i <= mid && j <= r){if(a[i] > a[j]){temp[k ++] = a[j ++];ans += mid - i + 1;//因为前半部分已经排好序了,后面的数都比这个数大 }else {temp[k ++] = a[i ++];}}while(i <= mid){temp[k ++] = a[i ++];}while(j <= r){temp[k ++] = a[j ++];}for(i = l; i <= r; i ++){a[i] = temp[i];}}void merge_sort(int l,int r){if(l == r)return ;int mid = (l + r) >> 1;merge_sort(l ,mid);merge_sort(mid + 1,r);merge(l,r);}int main(){int Tcase;scanf("%d",&Tcase);for(int ii = 1; ii <= Tcase; ii ++){ans = 0;int n;scanf("%d",&n);for(int i = 1; i <= n; i ++)scanf("%d",&a[i]);merge_sort(1,n);//for(int i = 1; i <= n; i ++)//cout << a[i] << " ";//cout << endl; cout << "Scenario #"<<ii << ":" << endl;cout << ans << endl << endl;}return 0;}


0 0