도구스개발

고속 아다마르 변환(XOR 합성곱) 계산기

XOR·AND·OR 합성곱을 O(n log n)에 계산하고 O(n²) 정답지와 나란히 놓아 정확히 일치하는지 보여 줍니다. 회전인자가 ±1뿐이라 정수 입력이면 반올림 없이 정수 답이 그대로 나옵니다.

쉼표·공백으로 구분 — 지금 4개

지금 4개. 길이가 달라도 됩니다

c[i] = Σ_{j ⊕ k = i} a[j]·b[k]

70, 68, 62, 60

길이 4로 채워 계산했습니다 · O(n²) 정답지와 정확히 일치

iab변환 a변환 b결과 c
00015102670
10126-2-268
21037-4-462
311480060
O(n²) 정답지와 일치하는가정확히 일치 (반올림 없음)
합의 항등식 Σc = (Σa)(Σb)260 = 10 × 26
곧이곧대로면 곱셈 횟수16
변환을 쓰면 (덧셈 포함)28
몇 배 적은가0.6
계산 근거 — XOR (아다마르 변환)H: (u, v) ← (u+v, u−v) 를 len = 1, 2, 4, … 로
c = H⁻¹( H(a) ⊙ H(b) ), H⁻¹은 H를 한 번 더 하고 n으로 나누기
변환을 씌우면 합성곱이 «점끼리 곱하기»로 바뀝니다. 이것이 FFT와 같은 발상입니다.
FFT와 달리 부동소수점 오차가 아예 없습니다. FFT는 복소수 회전인자를 쓰므로 정수 입력에도 오차가 끼어 답을 반올림해야 하고, 값이 커지면 그 반올림이 틀리기도 합니다. 아다마르 변환의 회전인자는 ±1 뿐이라 곱셈 자체가 없습니다 — 더하기와 빼기만 합니다. 그래서 위의 검산이 「근사가 아니라 정확히 일치」로 나옵니다.
역변환이 순변환과 같습니다. H² = n·I이라 같은 변환을 한 번 더 하고 n으로 나누면 제자리로 돌아옵니다. 역변환 코드를 따로 쓸 필요가 없다는 뜻이고, 구현이 몇 줄로 끝나는 이유이기도 합니다. 제타 변환도 뺄셈으로 바꾸기만 하면 뫼비우스가 됩니다.
왜 FFT를 쓰지 않나요. FFT가 푸는 것은 «인덱스가 더해지는» 합성곱 c[i] = Σ_{j+k=i} a[j]b[k] 입니다. 인덱스가 XOR 되는 것과 더해지는 것은 전혀 다른 연산이라 서로 대신할 수 없습니다. 비트마스크 DP 나 부분집합을 다루는 문제에서 나오는 것은 대개 이쪽입니다.
길이는 2의 거듭제곱으로 채웁니다. 인덱스를 비트로 다루므로 길이가 2의 거듭제곱이어야 합니다. 모자라면 0으로 채우는데, 0을 채워도 답이 달라지지 않는 것은 곱이 0이 되어 어디에도 보태지 않기 때문입니다. 두 수열의 길이가 달라도 긴 쪽에 맞춰 채웁니다.

사용 방법

  1. 1두 수열을 넣습니다. 길이가 달라도 되고 2의 거듭제곱이 아니어도 됩니다.
  2. 2XOR·AND·OR 중에서 어떤 합성곱인지 고릅니다.
  3. 3결과가 O(n²) 정답지와 정확히 일치하는지 확인합니다.
  4. 4변환한 값을 보면 왜 「점끼리 곱하기」로 바뀌는지 보입니다.

자주 묻는 질문

c[i] = Σ_{j⊕k=i} a[j]·b[k]로, 「인덱스를 XOR 하면 i가 되는 모든 짝의 곱을 더한 것」입니다. 비트마스크 DP나 부분집합을 다루는 문제에서 자주 나옵니다. 곧이곧대로 하면 O(n²)이지만 아다마르 변환을 쓰면 O(n log n)입니다.

FFT는 인덱스가 「더해지는」 합성곱을, 아다마르 변환은 인덱스가 「XOR 되는」 합성곱을 풉니다. 전혀 다른 연산이라 서로 대신할 수 없습니다. 뼈대는 같지만 회전인자가 FFT는 복소수, 아다마르는 ±1뿐입니다.

회전인자가 ±1뿐이라 곱셈 자체가 없고 더하기와 빼기만 하기 때문입니다. FFT는 복소수 회전인자를 쓰므로 정수 입력에도 부동소수점 오차가 끼어 답을 반올림해야 하고, 값이 커지면 그 반올림이 틀리기도 합니다. 아다마르 변환은 정수 입력이면 정수 답이 그대로 나옵니다.

순변환을 한 번 더 하고 n으로 나누면 됩니다. H² = n·I이기 때문입니다. 역변환 코드를 따로 쓸 필요가 없어 구현이 몇 줄로 끝납니다.

됩니다. OR은 부분집합 합(제타 변환)을, AND는 상위집합 합을 씌운 뒤 점곱하고 되돌립니다. 뫼비우스 변환은 제타의 덧셈을 뺄셈으로 바꾼 것뿐입니다. 셋 다 O(n log n)이고 정수 연산만 씁니다.

0으로 채웁니다. 인덱스를 비트로 다루기 때문에 2의 거듭제곱이어야 합니다. 0을 채워도 답이 달라지지 않는 것은 곱이 0이 되어 어디에도 보태지 않기 때문입니다.

비트마스크 DP에서 부분집합을 합칠 때, 선형대수에서 XOR 기저를 다룰 때, 그리고 부호이론(월시 함수)과 CDMA 확산 코드에도 쓰입니다. 경쟁 프로그래밍에서는 「XOR이 k인 짝의 개수」류 문제의 표준 도구입니다.

전송되지 않습니다. 계산은 모두 브라우저 안에서 이루어지고 넣은 값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 길이를 2의 거듭제곱으로 채웁니다. 모자란 자리는 0입니다.
  • 정수 입력이면 정수 답이 정확히 나옵니다. 반올림하지 않습니다.
  • 값이 매우 크면 자바스크립트 수의 안전 범위(2⁵³)를 넘을 수 있습니다.
  • FFT를 대신하지 못합니다. 인덱스가 더해지는 합성곱은 다른 문제입니다.
  • 역변환은 순변환을 한 번 더 하고 n으로 나눈 것입니다.
  • AND·OR는 아다마르가 아니라 제타·뫼비우스 변환을 씁니다.
  • 길이는 4096까지 다룹니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.