Game with Segment Tree

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

요약
번호가 붙은 리프를 가진 포화 이진 트리에서 두 사람이 번갈아 리프가 [a, b]에 속하는 서브 트리를 가져가며, 최선의 전략에서 승자를 판정한다.
난이도

어려움10점 중 8점

유형
게임 이론, 트리, 구현
정답자
아직 제출이 없습니다

문제

승원이는 수열과 쿼리 998244353을 풀던 도중 도저히 풀이가 떠오르지 않아 옆자리에 있던 민재와 게임을 하려고 한다. 게임의 규칙은 아래와 같다.

  • 게임은 높이가 KK인 포화 이진 트리에서 진행된다. 포화 이진 트리의 각 리프 노드에는 아래 그림과 같이 번호가 1,,2,,⋯ ,2K−11, \\, 2, \\, \cdots, 2^{K - 1}로 연속적으로 부여되어 있다.

  • 게임은 승원이부터 시작하며, 자신의 차례에서 노드를 하나 선택해 그 노드의 서브 트리를 모두 가져간다. 단, 이때 선택한 서브 트리의 리프 노드의 번호는 \[a,,b]\[a, \\, b]에 속해야 하며, 일부라도 가져간 부분이 있으면 가져갈 수 없다.
  • 자신의 차례에서 더 이상 선택할 수 있는 노드가 남아있지 않다면 패배한다.

승원이와 민재는 이 게임의 달인이므로 최선의 전략으로 게임을 한다. 그 때 누가 게임을 이기는지 구하라.

입력

첫 번째 줄에 높이 KK와 게임의 개수 GG가 공백으로 구분되어 주어진다. (1≤K≤60(1\le K\le60, 1≤G≤200000)1\le G\le 200 000)

두 번째 줄부터 GG개의 줄에 걸쳐 한 줄에 하나씩 각 게임의 범위의 시작 aa와 범위의 끝 bb가 공백으로 구분되어 주어진다. (1≤a≤b≤2K−1)(1\le a\le b\le 2^{K-1})

출력

GG개의 줄에 걸쳐, 각 게임에서 승원이가 이기는 경우 "swlee0202"를, 민재가 이기는 경우 "mj1000j"를 한 줄에 하나씩 출력하라.

힌트

입출력의 양이 많으므로, 빠른 입출력을 사용하는 것을 권장합니다. 다음은 대표적인 언어에서 빠른 입출력을 이용하는 방법입니다.

  • C++: cin, cout을 사용한다면 main 함수 첫 줄에 std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios_base::sync_with_stdio(false);를 추가하고, 줄바꿈 시 std::endl 대신 '\n'을 출력해주세요. 이 경우 scanf를 비롯한 C의 입출력 함수는 사용할 수 없음에 유의해 주세요.
    • scanf/printf는 충분히 빠르므로 별도의 처리를 하지 않아도 괜찮습니다.
  • Java: Scanner와 System.out.println 대신 BufferedReader와 BufferedWriter를 사용해 주세요.
  • Python3, PyPy3: input() 대신 sys.stdin.readline().rstrip()을 사용해 주세요.

예제2

  1. 예제 1

    입력
    4 2
    1 1
    2 7
    
    예상 출력
    swlee0202
    mj1000j
    
  2. 예제 2

    입력
    3 1
    1 4
    
    예상 출력
    swlee0202