정수 세 개로 이루어진 삼중항 a=(xa,ya,za)와 b=(xb,yb,zb) 사이에 부분 순서 ≺를 다음과 같이 정한다.
a≺b⟺xa<xb, ya<yb, za<zb
세 좌표가 모두 커져야 a≺b가 성립한다.
삼중항 집합이 주어진다. 그 안에서 a1≺a2≺⋯≺ak를 만족하는 가장 긴 사슬을 찾아라.
입력은 데이터 집합 여러 개로 이루어진다. 데이터 집합 하나의 형식은 다음과 같다.
m n A B
x1 y1 z1
x2 y2 z2
...
xm ym zm
첫 줄의 m, n, A, B와 그 뒤 m개 줄에 적힌 xi, yi, zi는 모두 음이 아닌 정수다.
데이터 집합 하나는 삼중항 m+n개를 정한다. 그중 p1부터 pm까지는 입력에 직접 적혀 있고, i번째 삼중항 pi는 (xi,yi,zi)다. 남은 n개는 아래 생성기에 A와 B를 넣어 만든다.
int a = A, b = B, C = ~(1<<31), M = (1<<16)-1;
int r() {
a = 36969 * (a & M) + (a >> 16);
b = 18000 * (b & M) + (b >> 16);
return (C & ((a << 16) + b)) % 1000000;
}
이 코드의 연산은 모두 32비트 부호 있는 정수로 이루어진다. 곱셈이나 덧셈 결과가 32비트 범위를 넘으면 2의 보수로 순환하고, >>는 부호를 유지하는 산술 시프트다.
r()을 3n번 연달아 호출하면 반환값이 순서대로 xm+1, ym+1, zm+1, xm+2, ym+2, zm+2, …, xm+n, ym+n, zm+n이 된다.
1≤m+n≤3×105이고 1≤A,B≤216이다. 1≤k≤m+n인 모든 k에 대해 0≤xk,yk,zk<106이다.
입력의 마지막 줄에는 0이 네 개 있다. 모든 데이터 집합의 m+n을 더한 값은 2×106을 넘지 않는다.
데이터 집합마다 가장 긴 사슬의 길이를 한 줄에 하나씩 출력한다. pi1≺pi2≺⋯≺pik가 가장 길면 답은 k다.