---一種の超高速リバース

この問題では、特定のソートアルゴリズム----超高速シークエンスを解析する必要があります。
昇順に配列されるまでプロセス異なる整数N配列に隣接する2つの配列要素を切り替えることによりアルゴリズム。
出力超高速ソート01459を生成、91054の入力シーケンスのために。
あなたの仕事は、与えられた入力シーケンスの順序のために実行する必要がありますどのように多くの超高速スイッチング動作ソートに決定することです。
入力形式の
入力は、テストケースの数を含みます。
入力シーケンスの長さを有する場合を表す各テストケース入力整数nの最初の行、。
次のn行はそれぞれアイアイ、代表的な実施形態では、i行目のi番目のシーケンスを表すデータによって配列特異的なデータ入力整数入力します。
入力シーケンス入力の実施形態は、0の長さを含む場合、入力は、処理シーケンスの必要性を終了します。
出力フォーマット
処理すべき各入力シーケンス、整数演算の出力は、スイッチング動作の所定の入力シーケンスの代表は、各整数を、行をソートするの最小数を必要としました。
データ範囲
0≦<5000000≤N<500000、

0≤ai≤9999999990≤ai≤999999999
入力サンプル:
5
。9
。1
0
。5
。4
。3
。1
2
3
0

出力サンプル:
6
0

アイデア:番号2の隣接する時間、為替あたり逆の変化1の数

#include <cstdio>
using namespace std;
typedef long long LL;
const int N = 500010;
int n;
LL q[N], w[N];
LL merge_sort(int l, int r){
 if (l >= r)   return 0;
 int mid = l + r >> 1;
 LL res = merge_sort(l, mid) + merge_sort(mid + 1, r);
 int i = l, j = mid + 1, k = 0;
 while(i <= mid && j <= r)
 if (q[i] < q[j])   w[k ++] = q[i ++];
 else{
  w[k ++] = q[j ++];
  res += mid - i + 1;
 }   
 while(i <= mid)   w[k ++] = q[i ++];
 while(j <= r)     w[k ++] = q[j ++];
  for (i = l, j = 0; i <= r; i ++, j ++)   q[i] = w[j];
 return res;
} 
int main(){
 while(~scanf("%d", &n), n){
  for (int i = 0; i < n; i ++)   scanf("%d", &q[i]);
  printf("%lld\n", merge_sort(0, n - 1));
 }
 return 0;
}
公開された106元の記事 ウォン称賛67 ビュー5437

おすすめ

転載: blog.csdn.net/qq_45772483/article/details/104786325