BOJ 29150 - 기초적인 문제 (Python3)

2023. 9. 10. 20:41Diamond/Diamond V

SUAPC 2023 Summer B번 문제이며, 내가 출제한 세 번째 문제이다.

출제 여담은 SUAPC 2023 Summer 출제 후기에 충분히 썼으니 이번에는 이 문제의 수학적인 해결법에 대해 논하고자 한다. 에디토리얼에 있는 풀이 두 가지 대신 출제 때부터 마음 속에 품고 있었던 야매 풀이 하나와 어제 생각해 낸 제4의 풀이 이렇게 두 가지로.

 

그럼 본격적으로 풀이에 돌입해 보자.


문제

행렬식은 선형대수학에서 다루는 기초적인 대상 중 하나이다. 이항계수는 조합론에서 다루는 기초적인 대상 중 하나이다.

두 기초적인 대상을 섞은 문제는 기초적이므로, 다음 행렬의 행렬식을 구하는 문제는 기초적인 문제이다. A(a1,a2,,aN)=((aij1))i,j=((a10)(a11)(a1N1)(a20)(a21)(a2N1)(aN0)(aN1)(aNN1))

단, (NK)={N!K!(NK)!(NK)0(N<K)는 이항계수이다.

기초적인 문제는 쉽게 풀 수 있으므로, 쿼리마다 정수 a1,a2,,aN이 주어지면 위 행렬의 행렬식을 구해보도록 하자.

 

입력

첫 번째 줄에 쿼리의 수 Q가 주어진다. (1Q200)

두 번째 줄부터 2Q개의 줄에 걸쳐 쿼리에 대한 정보가 주어진다.

각 쿼리는 두 줄로 이루어져 있다. 쿼리의 첫 번째 줄에는 행렬의 크기 N이 주어지며, 두 번째 줄에는 N개의 음이 아닌 정수 a1,a2,,aN이 공백으로 구분되어 주어진다. (1N500; 0ai<1000000007)

 

예제 입력)

1
3
4 5 7

 

출력

한 줄에 하나씩 순서대로 detA(a1,a2,,aN)1000000007(=109+7)로 나눈 나머지를 출력한다. 정확하게는, detA(a1,a2,,aN)M(mod1000000007)인 정수 M을 출력한다. (0M<1000000007)

 

예제 출력)

3

 


내 코드

mod = 10**9+7
fact = [1]*501
for i in range(2,501):
    """ fact[N] = N! """
    fact[i] = (fact[i-1]*i)%mod
hyper_fact = [1]
for i in range(1,501):
    hyper_fact.append((hyper_fact[-1]*fact[i])%mod)
def inv(x): return pow(x,mod-2,mod) 
def vandermonde(N,a):
    ans = 1
    for i in range(1,N):
        for j in range(i):
            ans = (ans*(a[i]-a[j]))%mod
    return ans
for _ in range(int(input())):
    N,a = int(input()),list(map(int,input().split()))
    print((vandermonde(N,a)*inv(hyper_fact[N-1]))%mod)

 

일단 거두절미하고 문제의 정답은 다음과 같다. i=0N11i!1i<jN(ajai)

 

우선 야매 풀이는 다음과 같다.

n×n 행렬 X=(xij)의 행렬식은 σSn(sgn(σ)i=1nxiσ(i))이 되고, 이는 변수를 xij로 가지는 n차 다항식으로 볼 수 있다.

주어진 행렬 A(a1,,aNi번째 세로줄은 (aji1)의 꼴로, i1차 다항식임을 알 수 있다. 윗줄에 쓰여진 행렬식의 표현을 관찰한다면 xij는 동일한 j에 대해서 정확하게 한 번만 곱해진다는 사실을 알 수 있다. 그러므로 만일 j번째 열의 모든 원소가 정확하게 j1차 다항식이게 된다면, 행렬식은 j=1N(j1)=N(N1)2차 다항식이 된다.

인수정리를 응용해 보자. 임의의 ij에 대해서 ai=aj이게 되면, i번째 가로줄과 j번째 가로줄이 정확하게 같게 되므로, 행렬식의 성질(두 가로줄을 교환하면 행렬식의 부호가 바뀐다)에 의하여 detA(a1,,aN)=0이 된다. 그러므로 detA(ai,,aN)는 모든 ajaj를 인수로 가진다.

1i<jN(ajai)N(N1)2차 다항식이 되므로, detA(a1,,aN)=k1i<jN(ajai)이 적당한 상수 k에 대해서 성립한다. 또한 ai=i1를 대입하였을 시 1i<jN((j1)(i1))=j=2N(i=1j1(j1))=j=2N(j1)!=i=0N1i!이 되며 A(0,1,,N1)은 대각성분이 각각 (00),(11),,(N1N1)인 삼각행렬이 되므로, 행렬식이 1이 된다.

따라서 k=0N11i!이 되고, 식을 정리하여 답을 얻을 수 있다.

 

네 번째 풀이는 그냥 행렬을 통째로 행연산을 반복하여 취함으로서 얻을 수 있다. 모든 열이 ai만 다르고 동일한 형태를 가지고 있으므로, (i,j)-component의 최저차항을 지우기 위해서 elementary row operation을 이용하면 임의의 k에 대해서 (k,j)-component의 최저차항까지 전부 사라진다.

반복적인 elementary row operation을 통해서 각 열에 최고차항만 남길 수 있고, 그렇게 해서 얻어진 행렬은 다음과 같이 Vandermonde matrix와 굉장히 유사한 형태를 띄게 된다.

(1a1a1N2(N2)!a1N1(N1)!1a2a2N2(N2)!a2N1(N1)!1aN1aN1N2(N2)!aN1N1(N1)!1aNaNN2(N2)!aNN1(N1)!)

공통된 상수를 행렬식 앞으로 꺼내주고, Vandermonde determinant를 계산해 주면 결과를 얻을 수 있다.

 

이로서 29150번의 풀이를 마친다.

 

 

728x90

'Diamond > Diamond V' 카테고리의 다른 글