BOJ 13318 위험한 해싱

2020. 1. 19. 13:48알고리즘 문풀/BOJ 연습

https://www.acmicpc.net/problem/13318

 

13318번: 위험한 해싱

string matching 알고리즘에는 여러 가지가 있다. KMP 알고리즘이나 Boyer­Moore 알고리즘이 그 예시이다. 하지만 지구이는 KMP를 이해할 수 없었고, Boyer­Moore는 시간복잡도가 너무 컸다. 결국 지구이는 틀릴 확률이 있지만, 간단한 방법인 해싱을 즐겨 사용하게 되었다. 해싱은 문자열을 숫자 하나로 바꾸는 해시 함수를 하나 정의한 후, 이 값이 같은지 다른지를 통해 문자열이 같은지 판별하는 방법이다. 지구이는 해시 함수를 다음

www.acmicpc.net

풀이

두 해시값을 뺀 다항식을 생각하면, 그 다항식은 아래와 같은 조건을 만족해야 한다.

  • degf<300000\deg f < 300000
  • f(x)=a0+a1x1++adxdf(x) = a_{0} + a_{1}x^{1} + \cdots + a_{d}x^{d}에서, 26<ad<26-26 < a_{d} < 26
  • f(23)=f(29)==f(67)=0f(23) = f(29) = \cdots = f(67) = 0 mod\text{mod} 109+710^{9} + 7

하지만 다항식 하나에 10개의 영점을 강제하기는 너무 어렵다.

그래서 생각하기를 f1(23)=0f_{1}(23) = 0을 만족하는 계수가 작은 다항식 f1(x)f_{1}(x)를 찾고, 똑같이 f2(29)=0f_{2}(29) = 0을 만족하는 계수가 작은 다항식 f2(x)f_{2}(x)를 찾고, ... 그렇게 f(x)=f1(x)f2(x)f10(x)f(x) = f_{1}(x)f_{2}(x) \cdots f_{10}(x)로 쓰면 되지 않을까? 계수가 작은 다항식끼리 곱해서 계수가 많이 커지지는 않을 것 같다.

 

그럼 이제 fi(x)f_{i}(x)를 잘 찾는 문제가 된다. 다항식을 10개로 쪼갰으니 평균 차수가 3000030000 이하여야 한다. 그런데 허탈하게도 fi(x)f_{i}(x)는 다음 형태로만 잡아줘도 충분하다.

fi(x)=1±xα±xβ f_{i}(x) = 1 \pm x^{\alpha} \pm x^{\beta}

 

대충 생각해 보면, p=109+7p = 10^{9} + 7의 원시근이 많으니까 대부분 xαx^{\alpha}xβx^{\beta}는 다를 거고, 각각 3000030000개 정도 더하고 빼면 하나쯤 0이 나올 만하다. 이론적 근거가 있는지는 모르겠다. 있다면 제보해 주시길.

 

어쨌든 저 다항식들을 싸그리 곱해도 계수가 ±5\pm 5는 넘어가지 않는 것 같다. Output only이기 때문에 충분한 디버깅을 거쳐서 기분좋게 한 방에 맞을 수 있다.