ICPC WF 연습 (3/7)
Flip Flow
모래시계를 시뮬레이션 하는 문제이다.
시키는 대로 구현하면 된다.
Ascent Sequences
다음 조건을 모두 만족하는 길이 의 수열 의 가짓수를 구하는 문제이다:
- 모든 원소는 음이 아닌 정수이다.
- . 여기서, 는 에서 증가한 횟수.
- "201 패턴"이 존재하면 안된다.
대충 다음과 같은 생각을 하였다:
- 문제에서 찾고자 하는 수열은 다음 두 수열을 적당히 합쳤다고 생각해도 된다:
- 는 혹은 이보다 하나 작은 값.
- 계단 형태로 감소하는 수열
- 각 수열 모두 적당한 DP로 해결할 수 있다. 나는 크기의 DP를 생각하였다.
- 이제 적당히 합쳐서 가짓수를 세면 된다.
하지만, 결국 풀지 못했다. 더 많은 관찰이 필요한 듯 하다.
Buggy Combination Lock
두 개의 수열 , 가 있다. 다음과 같은 연산을 사용하여, 수열 를 로 바꿀 때, 연산 사용의 최소 횟수를 구하는 문제이다.
- 과 에 모두 을 더하거나, 을 더한다.
- Index는 modulo , 원소의 값은 modulo 에서 생각한다.
Index 에 대하여 적용한 값을 라고 하자. 이며, 를 만족하면서 가 최소가 되는 를 찾으면 된다.
식을 조금 변형하면, 를 얻을 수 있다. 즉, 형태로 나타낼 수 있으며, 또한 가 성립한다.
이제, Case를 나누자:
- 인 경우,
- 이라면, 해가 존재하지 않는다.
- 이라면, 모든 에 대해 해가 존재한다. (즉, 해가 총 개 존재한다.)
- 라고 하자.
- 함수 는 개의 Piecewise-linear function의 합으로 표현할 수 있다.
- 따라서, 의 모든 local minima와 maxima를 전부 알아낼 수 있다.
- 즉, 를 에 구할 수 있다.
- 인 경우,
- , 이므로, 가능한 의 값은 최대 두 개이다.
- 가능한 모든 에 대해, 의 값을 계산하면 충분하다.
따라서, 의 시간 복잡도로 답을 계산할 수 있다.
틀리기 쉬운 요소가 상당히 많았고, 나는 그런 부분에 대해 모두 한 번씩 틀렸었다.
Cyclic Shifts
문자열 에 대해, 문자열 가 사전순으로 최소가 되는 중, 가장 작은 를 Cyclic shift라고 정의하자. 길이 의 문자열 가 주어질 때, 모든 Prefix에 대하여 Cyclic shift의 값을 구하는 문제이다.
찾아보니 논문이다. 길이 인 Prefix의 Cyclic shift 값을 모두 알고 있을 때, 단 세 번의 추가 비교 연산만으로 -Prefix의 Cyclic shift 값을 알아낼 수 있다고 한다.
Exclusive Training
개의 벡터 가 주어진다. 각 에 대하여, 다음 최댓값을 구하는 문제이다:
- , 인 를 고정하자.
- , 를 모두 만족하는 모든 에 대하여, 의 최댓값.
먼저, 가 서로 다르므로, 의 오름차순으로 정렬하자.
Key가 인 Segment Tree를 생각하자. 이 Segment Tree는 다음 연산을 지원한다:
- 구간에 더하기.
- 각 에 대하여, 지금까지 자신이 가졌던 값의 최댓값을 라고 하자. 구간에서 의 최댓값 구하기.
가 작은 부터 차례대로 보면서, 구간 에서 최댓값이 문제의 답이 된다. 문제의 답을 구한 후, 구간 에 를 더해주면 된다.
Segment Tree의 이러한 연산은 Lazy Propagation Technique를 이용하면 효율적으로 처리할 수 있다. Propagation 정보로
- 구간에 더해주어야 하는 값
- 이 구간에 더해주어야 하는 값의 Prefix sum의 최댓값 (에 더해주어야 하는 값)
을 들고 있어야 한다.
전체 시간 복잡도는 , 공간 복잡도는 이다.
상당히 재미있는 테크닉이다.