이 문제에서는 특정 정렬 알고리즘을 분석해야한다. 알고리즘은 시퀀스는 오름차순으로 정렬 될 때까지 두 개의 인접한 시퀀스의 요소를 교환하여 N 개의 별개의 정수들의 시퀀스를 처리한다. 입력 시퀀스
9 1 0 5 4
울트라 이것은 QuickSort는 출력을 생성
0 1 4 5-9.
당신의 작업은 매우 이것은 QuickSort가 주어진 입력 순서를 정렬하기 위해 수행 할 필요가 얼마나 많은 스왑 작업을 결정하는 것입니다.
울트라 이것은 QuickSort는 출력을 생성
당신의 작업은 매우 이것은 QuickSort가 주어진 입력 순서를 정렬하기 위해 수행 할 필요가 얼마나 많은 스왑 작업을 결정하는 것입니다.
입력
입력은 여러 테스트 케이스가 포함되어 있습니다. 입력 시퀀스의 길이 - 모든 테스트 케이스는 하나의 정수 n <50을 포함하는 선으로 시작한다. 다음 상기 N 라인의 각각은 [I] ≤ 999,999,999, i 번째 입력 시퀀스 요소 ≤ 단일 정수 0을 포함한다. 입력은 길이 N의 시퀀스를 종료한다 = 0이 시퀀스가 처리해서는 안된다.
산출
모든 입력 순서를 들어, 프로그램이 정수 연산을 포함하는 단일 행을 인쇄, 필요한 스왑 작업의 최소 수는 지정된 입력 순서를 정렬합니다.
샘플 입력
5 9 1 0 5 4 3 1 2 3 0
샘플 출력
6 0
#INCLUDE <cstdio> #INCLUDE <iostream> #INCLUDE <CString을> #INCLUDE <알고리즘> #INCLUDE <큐> #INCLUDE <적층> #INCLUDE < 설정 > #INCLUDE <벡터> #INCLUDE <지도> CONST의 INT maxn = 5e5 + (5) ; 타입 정의 긴 긴 LL; 사용하는 네임 스페이스 표준을; 구조체 노드 { LL의 L, R; LL 합계; } 트리 [maxn << 2 ]; int로 A [maxn, 서브 [maxn, 카본 나노 튜브를; 팔 굽혀 펴기 ( INT의 m) { 트리 [m] .sum = (트리 [m << 1 ] + 트리 .sum [m << 1 | 1 ] .sum); } // 무효 푸시 (INT의 m) // { // 경우 (트리 [m] .lazy) // { // 트리 [m << 1] = .lazy 트리 [m] .lazy; // 트리 [m << 1 | 1] = .lazy 트리 [m] .lazy; // 트리 [m << 1] = .sum 트리 [m]의 .lazy * (트리 [m << 1] .R 트리 [m << 1] 펜닐 + 1); // 트리 [m << 1 | 1] = .sum 트리 [m]의 .lazy * (트리 [m << 1 | 1] .R 트리 [m << 1 | 1] 펜닐 + 1); // 트리 [m] .lazy = 0; // } 공극 빌드 ( INT의 m, INT의 L, INT의 R) { 트리 [m] 펜닐 = L; 트리 [m] .R = R; 트리 [m] .sum = 0 ; 경우 (L == R) { 트리 [m] .sum = 0 ; 반환 ; } INT 중간 = (트리 [m] + 트리 .L [m] .R) >> 1 ; 빌드 (m << 1 , L, MID); 구축 (m << 1 | 1 , 중반 + 1 , R); 팔 굽혀 펴기 (m); 반환 ; } 공극 업데이트 ( INT의 m, INT의 인덱스, INT의 발) { 경우 (트리 [m] 펜닐 == 인덱스 && 트리 [m] 펜닐 == 트리 [m] .R) { 트리 [m] .sum ++ ; 반환 ; } INT 중간 = (트리 [m] + 트리 .L [m] .R) >> 1 ; 경우 (인덱스 <= MID) { 업데이트 (m << 1 인덱스, 발); } 다른 { 업데이트 (m << 1 | 1인덱스, 발); } 팔 굽혀 펴기 (m); 반환 ; } LL 쿼리 ( INT의 m, INT의 L, INT의 R) { 경우 (L> R) { 창 0 ; } 경우 (트리 [m] 펜닐 == && 트리 L [m] == .R R) { 복귀 트리 [m] .sum; } // 푸시 (m); INT 중간 = (트리 [m] + 트리 .L [m] .R) >> 1 ; 경우 (R <= MID) { 리턴 질의 (m << 1 , L, R); } 다른 경우 (L> MID) { 리턴 질의 (m << 1 | 1 , L, R); } 다른 { 리턴 질의 (m << 1 , L, MID) + 쿼리 (m << 1 | 1 중간 + 1 , R); } } INT 의 main () { INT의 N; 반면 (CIN >> N) { 경우 (N 개의 == 0 ) { 중단 ; } 에 대해 ( int로 I = 0 ; I <N은; I ++)는 scanf ( " % d의" , 서브 [I])와, [I]가 = 서브 [I]가, 정렬 방법 (이하, 서브 + N) INT의 크기 = 고유 (이하, 서브 + N) - 부; 위해 ( int로 = 1을 0 ; 나는 < N; 내가 ++ ) 이 [I] = LOWER_BOUND (이하, 서브 + 사이즈, A [I]) - 서브 + 1 ] 구축 ( 1 , 1 , 크기), LL 합 = 0 ; 대 ( INT의 t = 0 ; t <N ; t ++ ) { 합계 + = 쿼리 ( 1 , A [t] + 1 , 크기), 업데이트 (1 , A [t], 1 ); } 의 printf ( " % LLD \ 없음 " , 합); } 반환 0 ; }