아직 만들고 있는 페이지입니다.

이 페이지는 아직 만드는 중입니다. 보이는 내용은 바뀔 수 있습니다.

쿼터너리 컴퓨터

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

요약
0부터 3까지 값을 저장하는 N개 변수와 M개 덧셈·배타합 명령, 변수별 금지 초기값이 주어질 때 모든 입력에 대한 변수별 출력 합을 4로 나눈 나머지를 구합니다.
난이도

어려움10점 중 9점

유형
비트 연산, 수학, 조합론, 완전 탐색
정답자
아직 제출이 없습니다

문제

경근이는 새로운 컴퓨터를 발명했다. 이 컴퓨터는 다른 컴퓨터와 달리 이진법이 아니라 사진법으로 자료를 저장한다.

이 컴퓨터에서 p+qp + q와 p⊕qp \oplus q의 연산 결과는 아래 표와 같다. 표에서 행은 pp, 열은 qq이다.

p+qp + q

++0123
00123
11230
22301
33012

p⊕qp \oplus q

⊕\oplus0123
00123
11032
22301
33210

경근이는 자신이 발명한 컴퓨터가 너무나 혁신적이라고 생각해서, 한시라도 빨리 써 보고 싶은 마음에 컴퓨터를 직접 만들었다.

예산을 아주 적게 들여 임시로 만든 것이라서 이 컴퓨터는 변수를 NN개만 저장하고, 각 변수에는 0 이상 3 이하의 정수 하나만 들어간다. 경근이는 편의상 각 변수에 0 이상 N−1N - 1 이하의 번호를 붙였고, ii번 변수를 viv_i라고 부르기로 했다.

경근이는 시간과 정성을 들여 꼭 필요하다고 판단한 기본 명령 네 가지를 만들었다.

  • addv x y z (0≤x,y,z≤N−10 \le x, y, z \le N - 1, xx, yy, zz는 모두 정수): vxv_x에 vy+vzv_y + v_z의 값을 대입한다.
  • xorv x y z (0≤x,y,z≤N−10 \le x, y, z \le N - 1, xx, yy, zz는 모두 정수): vxv_x에 vy⊕vzv_y \oplus v_z의 값을 대입한다.
  • addc x y z (0≤x,y≤N−10 \le x, y \le N - 1, 0≤z≤30 \le z \le 3, xx, yy, zz는 모두 정수): vxv_x에 vy+zv_y + z의 값을 대입한다.
  • xorc x y z (0≤x,y≤N−10 \le x, y \le N - 1, 0≤z≤30 \le z \le 3, xx, yy, zz는 모두 정수): vxv_x에 vy⊕zv_y \oplus z의 값을 대입한다.

경근이는 기본 명령 MM개를 나열한 코드를 작성했다. 코드를 컴파일하면 프로그램이 생성된다. 이 프로그램은 명령을 실행하기 전에 각 변수 viv_i에 저장할 값을 입력받고, 코드에 있는 MM개의 명령을 순서대로 하나씩 실행한 다음, 모든 명령을 실행한 뒤 각 변수 viv_i에 저장되어 있는 값을 출력한다. 편의상 입력을 a0,a1,…,aN−1a_0, a_1, \dots, a_{N-1}로, 출력을 b0,b1,…,bN−1b_0, b_1, \dots, b_{N-1}로 나타내자.

아쉽게도 경근이의 구현 실수 탓에, 모든 변수 viv_i에는 처음에 저장할 수 없는 값 fif_i (0≤fi≤30 \le f_i \le 3)가 하나씩 있다. 따라서 ai≠fia_i \ne f_i여야 하므로 aia_i로 가능한 값은 0, 1, 2, 3 중 fif_i가 아닌 세 수이다. 그러므로 가능한 입력은 모두 3N3^N가지이다.

경근이는 프로그램을 완벽하게 작성했는지 알고자 가능한 입력을 모두 살펴보기로 한다. 결과를 기록하려고 NN쪽으로 된 노트를 샀고, 각 쪽에 0 이상 N−1N - 1 이하의 정수 번호를 붙였다. 경근이는 가능한 입력을 모두 만들어 하나씩 프로그램에 넣어 보면서, 각 입력에 대한 프로그램의 출력 b0,b1,…,bN−1b_0, b_1, \dots, b_{N-1}을 얻은 뒤 bib_i의 값을 ii번 쪽에 적는다.

모든 입력을 다 살펴본 뒤 ii번 쪽에 적혀 있는 수의 합을 sis_i라고 하자. 경근이는 작업을 시작하기 전에 최소한의 안전 장치를 마련하고자 모든 ii에 대해 sis_i를 4로 나눈 나머지를 알고자 한다.

입력

첫째 줄에 변수의 수 NN (1≤N≤181 \le N \le 18)과 명령의 수 MM (0≤M≤4000 \le M \le 400)이 주어진다.

둘째 줄에 f0,f1,…,fN−1f_0, f_1, \dots, f_{N-1} (0≤fi≤30 \le f_i \le 3)이 공백을 사이에 두고 주어진다. 여기서 fif_i는 명령을 실행하기 전에 변수 viv_i에 저장할 수 없는 값이며, 정수이다.

이후 MM개의 줄에 명령이 실행되는 순서대로 한 줄에 하나씩 주어진다. 이 중 jj (1≤j≤M1 \le j \le M)번째 줄의 형식은 다음과 같고, 주어지는 수는 모두 정수이며 공백 하나로 구분된다.

  • 0 x y z (0≤x,y,z≤N−10 \le x, y, z \le N - 1): jj번째로 실행되는 명령이 addv x y z임을 나타낸다.
  • 1 x y z (0≤x,y,z≤N−10 \le x, y, z \le N - 1): jj번째로 실행되는 명령이 xorv x y z임을 나타낸다.
  • 2 x y z (0≤x,y≤N−10 \le x, y \le N - 1, 0≤z≤30 \le z \le 3): jj번째로 실행되는 명령이 addc x y z임을 나타낸다.
  • 3 x y z (0≤x,y≤N−10 \le x, y \le N - 1, 0≤z≤30 \le z \le 3): jj번째로 실행되는 명령이 xorc x y z임을 나타낸다.

출력

sis_i를 4로 나눈 나머지를 tit_i라고 할 때, 첫째 줄에 t0,t1,…,tN−1t_0, t_1, \dots, t_{N-1}을 공백을 사이에 두고 출력한다.

예제4

  1. 예제 1

    입력
    2 2
    2 3
    0 0 1 0
    1 1 1 0
    
    예상 출력
    1 0
    
  2. 예제 2

    입력
    1 0
    0
    
    예상 출력
    2
    
  3. 예제 3

    입력
    1 4
    2
    2 0 0 3
    3 0 0 1
    2 0 0 2
    3 0 0 2
    
    예상 출력
    2
    
  4. 예제 4

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