더 빠른 정렬

시간 제한1초메모리 제한128 MB

요약
주어진 MINRUN마다 Timsort의 런 분할을 그대로 수행해 부분 배열의 개수와 bad element의 개수를 구한다.
난이도

보통10점 중 7점

유형
시뮬레이션, 투 포인터, 누적 합
정답자
아직 제출이 없습니다

문제

올해부터 ACM-ICPC 월드 파이널에서 파이썬을 쓸 수 있다. 그 기념으로 파이썬에 관한 재미있는 사실 하나를 소개한다.

파이썬은 팀소트라는 정렬 알고리즘을 쓴다. 이미 순서가 맞는 부분배열로 배열을 나누고, 각 부분배열을 삽입정렬한 다음, 정렬된 부분배열을 합치는 방식이다. 그래서 순서대로 놓인 원소가 길게 이어질수록 정렬이 빨라진다.

이 문제는 배열을 부분배열로 나누는 과정만 다룬다. 현재 위치를 ii라 하고, 배열이 끝날 때까지 다음 두 단계를 반복한다.

  1. 위치 ii에서 시작해 증가하거나 유지되는(ai≤ai+1≤ai+2≤⋯a_i \le a_{i+1} \le a_{i+2} \le \cdots) 부분배열과 감소하는(ai>ai+1>ai+2>⋯a_i > a_{i+1} > a_{i+2} > \cdots) 부분배열을 각각 가능한 한 길게 잡고, 둘 중 더 긴 쪽을 고른다.
  2. 부분배열의 길이가 MINRUNMINRUN보다 작으면 뒤에 있는 원소를 하나씩 더 가져와 길이를 MINRUNMINRUN으로 맞춘다. 이때 가져온 원소를 나쁜 원소라고 부른다. 길이를 맞추기 전에 배열이 끝나면 거기서 멈춘다.

다음 위치는 방금 만든 부분배열의 바로 뒤이다.

MINRUN이 3, 4, 5일 때 배열이 부분배열로 나뉘는 모습과 나쁜 원소(BAD)의 위치

MINRUNMINRUN이 작으면 합쳐야 할 부분배열이 많아지고, MINRUNMINRUN이 크면 나쁜 원소가 많아져 삽입정렬이 힘들어진다. 그래서 적당한 MINRUNMINRUN을 잡는 것이 중요하다. 부분배열을 합치는 과정 때문에 N/MINRUNN/MINRUN이 2의 거듭제곱에 가까우면 좋다는 조건도 있지만, 이 문제에서는 고려하지 않는다.

MINRUNMINRUN 값이 주어질 때마다 부분배열의 개수와 나쁜 원소의 개수를 구하라.

입력

첫째 줄에 배열의 길이 NN이 주어진다. (5≤N≤100 0005 \le N \le 100\,000)

둘째 줄에 배열의 원소 NN개가 주어진다. 각 원소의 절댓값은 10910^9 이하이다.

셋째 줄에 쿼리의 개수 QQ가 주어진다. (1≤Q≤100 0001 \le Q \le 100\,000)

넷째 줄부터 QQ개의 줄에 걸쳐 MINRUNMINRUN 값이 한 줄에 하나씩 주어진다. (2≤MINRUN≤N2 \le MINRUN \le N)

출력

각 쿼리마다 부분배열의 개수와 나쁜 원소의 개수를 공백으로 구분해 한 줄에 출력한다.

예제2

  1. 예제 1

    입력
    15
    2 4 4 3 -1 -2 -2 5 6 5 4 3 2 3 4
    3
    3
    4
    5
    
    예상 출력
    5 0
    4 3
    3 5
    
  2. 예제 2

    입력
    5
    7 7 7 7 7
    4
    2
    3
    4
    5
    
    예상 출력
    1 0
    1 0
    1 0
    1 0