기분 좋게 12시쯤 일어나서 디스코드를 보니 9시에 SCPC가 시작해 있었다.

1. 연속 1

0011로 이루어진 문자열이 주어진다. SS의 비용을 지불하고 0011로, EE의 비용을 지불하고 1100으로 바꿀 수 있을 때, 연속된 11이 한 묶음 이내가 되게 하는 최소 비용을 구하는 문제이다.

각 인덱스에 대해, 이 인덱스 이전을 00...0011...1100...0011...11로 만들 수 있는 최소 비용과, 이 인덱스 뒤를 11...1100...1111...1100...11로 만들 수 있는 최소 비용을 DP로 구한 다음, 더해서 최솟값을 찾는다. 이후 전부를 00으로 만드는 비용과 비교하여 출력하면 된다.

2. 라운드 로빈

자연수가 적힌 공 NN개가 주어진다. 이들을 모두 큐에 넣고, 큐에서 공을 하나 뺀 뒤 적힌 수를 11 줄여 다시 넣는 시행을 반복한다. 이때 00이 되면 다시 넣지 않는다. 이때 쿼리가 주어지는데, XX번째로 큐에서 뽑히는 공의 번호, 즉 적힌 수가 아닌 처음 들어온 순서를 출력하는 문제이다.

몇 번째 주기에서 큐에 들어 있는 공이 11개 줄어드는지는 정렬을 이용하면 쉽게 구할 수 있다. 이후 이분 탐색을 통해 XX번째로 큐에서 공이 빠질 때 큐에 들어 있던 공의 개수를 알 수 있다. 이를 MM이라 하자.

NN부터 M+1M+1개의 공이 큐에 들어 있는 동안 지나간 턴 수는 미리 구해놓을 수 있고, 남은 턴 수가 YY라 하면 큐에 남아 있는 공 중 들어온 처음에 순서대로 Y%MY\%M번째에 위치한 공이 답이 된다. 이를 구하기 위해서 나는 처음 들어온 순서대로 세그먼트 트리에 넣어 두고 공이 하나 빠질 때마다 해당 위치를 제거하는 방법을 사용했다. 그러면 이분 탐색을 통해 남아 있는 공 중 Y%MY\%M번째가 무엇인지 알 수 있다. 이때 오프라인 쿼리를 이용해 XX가 작은 것부터 처리해야 AC를 받는다.

3. 방범 시스템

좌표평면에 NN개의 정점과 가중치가 주어지고, 쿼리로 정점이 주어진다. 이때 NN개의 정점 모두에 대해 택시 거리와 가중치를 곱한 것의 합을 출력하는 문제다.

택시 거리이므로 xx축과 yy축을 나눠서 생각할 수 있다. 한 축에 대해, 쿼리로 들어온 좌표가 aa라고 하자. 이때 좌표 bb에 위치한 가중치 cc의 정점은 a<ba<b일 때 ca+bc-ca+bc, aba \geq b일 때 cabcca-bc를 답에 더해주게 된다.

이는 aa에 대한 일차함수 형태이고, 오프라인 쿼리를 이용하면 케이스의 변환이 최대 한 번 일어나므로 답을 구할 수 있다.

4. 수열 탈집중화

길이 NN의 수열 AA가 주어질 때, 구간의 모든 수를 해당 구간의 최댓값, 혹은 최솟값으로 만드는 시행을 하여 ii,jN(A[i]A[j])2\sum \limits _{i \leq i, j \leq N} (A[i]-A[j])^{2}를 최소화하는 문제였다. 이때 가능한 답 중 최소 시행인 것을 아무거나 출력해야 한다.

구간의 모든 수를 최솟값 혹은 최댓값 중 하나로 만들고, 개수를 최대한 비슷하게 맞추면 된다고 생각했다. 따라서 22번 이내의 시행으로 할 수 있는 것 같지만, 구현이 더러울 것 같아 패스했다.

5. 보물찾기

NN개의 정점, MM개의 간선으로 이루어진 무방향 그래프가 주어진다. 이때 각 정점을 AA 혹은 BB가 소유한다. 몇 개의 정점에는 보물이 묻혀 있다. 아래와 같은 게임을 반복하여, 보물이 위치한 정점에 무한히 반복할 수 있으면 AA가, 아니면 BB가 이긴다. 이때 출발점에 따라 누가 이기는지 출력하는 문제이다.

게임: 처음에 한 정점에 말을 놓는다. 말이 놓인 정점을 소유한 사람이, 연결된 정점 중 한 곳에 말을 옮긴다. 이를 반복한다.

우선 바로 승패가 결정되는 조건을 생각해보았다. 만약 출발점에서 AA가 소유한 정점 둘이 연결되어 있고, 둘 중 하나라도 보물이 있다면 둘을 왕복하는 것을 반복하여 AA가 이긴다. 여기에 AA가 소유한 정점만으로 열결되어 있는 정점을 출발점으로 하는 경우에 대해서도, 역시 AA가 이긴다.

만약 BB가 소유한 정점 둘이 연결되어 있고, 둘 모두에 보물이 없다면 둘을 왕복하는 것을 반복하여 BB가 이긴다. 여기에 BB가 소유한 정점만으로 연결되어 있는 정점을 출발점으로 하는 경우에 대해서도, 역시 BB가 이긴다.

위 경우를 잘 생각해보면 같은 소유자를 가진 연결된 정점끼리 유파를 이용해 union하는 것이 자연스럽다. 유한 시간 내에 소유자의 마음대로 말을 이동시킬 수 있기 때문이다. 이렇게 묶인 묶음들을 AA묶음, BB묶음이라 하자.

이제 남은 묶음을 분류하면 다음과 같다.

  1. 보물이 단 한 개도 없는 AA묶음
  2. 보물이 있는 크기 1의 AA묶음
  3. 임의의 연결된 두 정점에 대해, 적어도 한 정점에 보물이 있는 BB 묶음

같은 소유자를 가진 정점은 모두 union되었으므로 AA묶음은 BB묶음과만, BB묶음은 AA묶음과만 연결되어 있다. 이 시점에 승패가 확실한 묶음은 모두 소유자가 승자이므로 1, 2, 3 케이스에서 이 시점에 승패가 확실해진 묶음으로 말을 이동시키는 전략은 없다. 따라서, 우리는 1, 2, 3 케이스만 남았다고 생각해도 좋다. 각 케이스를 분석해보자.

분석하기 전에, 어떤 이동에 대해서 상대방이 이를 계속 원상복귀시켜도 상대방이 이긴다면 이는 의미 없는 이동이 된다는 점을 기억하자. 또한, 묶음의 크기가 22 이상일 때 묶음 내에서 말을 계속 순환시키면 진다는 것 역시 기억하자.

1번의 경우, 3번 묶음으로 언젠가는 말을 이동시켜야 한다. 이때, 이동한 정점에 보물이 없다면, BB가 말을 무한히 원상복귀시켜 이긴다. 이동한 정점에 보물이 있다면, BB는 말을 무한히 원상복귀시킬 수 없다. 따라서 BB는 말을 다른 묶음으로 이동시켜야 하게 된다.

2번의 경우, 3번 묶음으로 말을 이동시켜야 하는데, 만약 이후에 BB가 말을 무한히 원상복귀시킨다면 BB는 진다. 따라서 BB는 말을 다른 묶음으로 이동시켜야 하게 된다.

3번의 경우, 2번 묶음에 말을 이동시킨다면 AA가 무한히 원상복귀시켜 이긴다. 1번 묶음으로 이동하기 전의 정점에 보물이 있다면 AA가 무한히 말을 원상복귀시켜 이긴다. 따라서 BB는 말을 보물이 없는 정점에서 1번 묶음으로만 이동시킬 수 있다.

이렇게 유의미한 이동을 모두 파악한 상태에서, 각 묶음을 정점으로, 말을 이동시킬 수 있는 묶음끼리의 관계를 단방향 간선으로 나타낸 그래프를 생각해보자. 이때 다른 묶음으로 갈 수 없는 모든 묶음은 소유자의 패배로 승패가 결정된다. 또한, 묶음 UU에 대해, UU에서 UU의 소유자의 승리로 승패가 결정된 묶음으로 갈 수 있다면 묶음 UU는 소유자가 승리한다. 마지막으로, 묶음 UU에 대해, UU에서 갈 수 있는 모든 묶음이 UU의 소유자의 패배로 승패가 결정된다면, 묶음 UU는 소유자가 패배한다.

위 관찰을 통해 묶음들의 승패를 최대한 결정했다고 하자. 그러나 아직 승패가 결정되지 않은 묶음이 존재할 수 있다. 이런 묶음을 애매한 묶음이라고 하자. 한 묶음에서 갈 수 있는 모든 묶음의 승패가 결정되었다면 해당 묶음은 애매할 수 없다.

이때 애매한 묶음 하나에서 말을 출발시켜보자. 애매한 BB 묶음의 경우, 여기서 갈 수 있는 묶음 중 승패가 결정된 묶음은 AA가 승리하는 묶음밖에 없다. 따라서 애매한 AA 묶음으로 말을 이동시키는 것이 최선이다. 이때, 애매한 AA 묶음에서 다른 애매한 BB 묶음으로 말을 넘기면, 이 과정이 반복된다. 애초에 AA묶음에서 BB묶음으로 “갈 수 있다”고 정의되기 위해서는 출발점 혹은 도착점에 보물이 있어야 하므로, 이렇게 무한히 사이클을 돌리면 AA가 이기게 된다. 따라서 모든 애매한 묶음은 AA의 승리이다.