2012-10-28 3 views
11

대용량 이모 트를 계산하는 방법 nr에 대해 142857을 모듈로 계산합니다. 142857에 특별한 것이 있습니까? 문제는 p은 우리가 루카스 정리를 사용할 수 있지만 무엇 142857.이항 계수 모듈로 142857

+0

142857 = 3^3 × 11 × 13 × 37. –

+2

'n'과 'r'의 크기는 어느 정도입니까? –

+1

CRT를 사용하고 계수 모듈로 11, 13, 27 및 37을 계산할 수 있기 때문에 factorisation이 도움이됩니다. –

답변

13

알고리즘에 대해 수행해야 소수 모듈 p 경우입니다 : 주요 능력에 기초 factorise

  • ; 142857 = 3^3 × 11 × 13 × 37
  • 각 나머지 전력을 모듈로 한 결과를 계산합니다.
  • 중국 잉여 정리를 사용하여 결과를 결합합니다.

(n above k) mod p^q 계산하려면 :

출처 : http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf, 정리 한

nn_j을 정의 p

에 의해 divible되지 않은 번호 1..n의 제품으로 (n!)_p을 정의 소거 j 최하위 디 (가) j 낮은 자리에서 운반 계산하지 k+r 추가시 1s 정의베이스 p

에서

운반 수로 e_j 정의 k 컴퓨팅 -베이스 p

에 GITS는 rn로 정의 if p=2 & q>=3-1이면

다음으로 (n above k) mod p^q := p^e_0 * s^e_(q-1) * concatenate(j=d..0)((n_j!)_p/((k_j!)_p*(r_j!)_p))의 결과는 하나의 기본 -p 숫자를 계산하는 연결의 각 용어와 함께 가장 낮은 0이 아닌 숫자를 계산하는 가장 낮은 숫자는 j입니다.

+0

얼마나 빠를까요? 코딩 해 보셨습니까? 나는 그것을 'n'을 인수 분해하는 것과 비교하고 싶다. –

+0

@ThomasAhle 필자는 그것을 구현하려고하지는 않았지만 몇 백 명이 넘는 숫자의 계승을 계산하려고한다면 잠시 기다려야 할 것입니다. –

+0

이항은'product [(k + 1) .. n]/product [1. .. (n-k)]'이므로 여전히 나눗셈이 필요하다. 그게이 질문의 요점이지, 그치? –

3

142857의 특별한 점은 7 * 142857 = 999999 = 10^6-1입니다. 이것은 a = 10 및 p = 7 인 Fermat의 Little Theorem에서 발생하는 요소로 모듈 식 등가성을 나타냅니다. 10 (mod 7). 즉, 대부분의 모듈로 999999를 모듈로 사용하고 마지막 모듈러를 7로 나눔으로써 최종 모듈로 줄일 수 있습니다. 이것의 장점은 모듈 분할이 k = 1,2,3,6에 대한 10^k 형식의 표현베이스에서 매우 효율적이라는 것입니다. 이런 경우 모두 숫자 그룹을 합치면됩니다. 이것은 casting out nines의 일반화입니다.

이 최적화는 하드웨어 기반 10 곱셈을 사용하면 실제로 의미가 있습니다. 정말 종이와 연필로해야한다면 잘 작동한다고 말할 수 있습니다. 이 문제는 최근에 온라인 경연 대회에 출현 한 것이므로 그 질문의 근원이라고 생각합니다.

+2

999999는 실제로 142857보다 더 선호하는 계수가 아니므로 문제 해결 방법을 알 수는 없습니다 ... 어쨌든 Granville이 필요합니다. –

+1

@ NiklasB. 손으로 계산을 쉽게 할 수 있습니다. 나는 이것이 소프트웨어 구현을 더 잘한다고 말한 적이 없다고 생각한다. – eh9

+0

그러나 질문은 가치를 계산할 수있는 방법 이었습니까? 그 맥락에서, 142857에 대해서는 특별한 것이 없습니다. –

12

실제로는 C(n,k) % mO(n) 시간으로 임의로 계산할 수 있습니다. m.

트릭은 처음부터 나중에 두 빼기, 프라임 파워 벡터로 n!, k!(n-k)!을 계산하고 나머지 모듈 m를 곱하는 것입니다.C(10, 4) 위해 우리는이 작업을 수행 : 어떤 부서가 없기 때문에

10! = 2^8 * 3^4 * 5^2 * 7^1 
4! = 2^3 * 3^1 
6! = 2^4 * 3^2 * 5^1 

는 따라서

C(10,4) = 2^1 * 3^1 * 5^1 * 7^1 

우리는이 쉽게 mod m을 계산할 수 있습니다. 트릭은 선형 시간에 n!과 친구들의 분해를 계산하는 것입니다. 소수점을 n까지 미리 계산하면 다음과 같이 효율적으로 처리 할 수 ​​있습니다. 1*2*...*9*10 제품의 각 짝수에 대해 분명히 2 인수를 얻습니다. 네 번째 숫자마다 두 번째 등을 얻습니다. 따라서 의 수는 n!이고 n/2 + n/4 + n/8 + ...입니다 (여기서 /은 바닥재입니다). 우리는 나머지 소수에 대해서도 똑같은 작업을 수행하며, O(n/logn) 소수는 n보다 작고 각각 O(logn)을 사용하기 때문에 분해가 선형입니다. 이 에라토스테네스의 체를 포함

func Binom(n, k, mod int) int { 
    coef := 1 
    sieve := make([]bool, n+1) 
    for p := 2; p <= n; p++ { 
     if !sieve[p] { 
      // Sieve of Eratosthenes 
      for i := p*p; i <= n; i += p { 
       sieve[i] = true 
      } 
      // Calculate influence of p on coef 
      for pow := p; pow <= n; pow *= p { 
       cnt := n/pow - k/pow - (n-k)/pow 
       for j := 0; j < cnt; j++ { 
        coef *= p 
        coef %= mod 
       } 
      } 
     } 
    } 
    return coef 
} 

때문에 소수가 미리 계산 또는 빠른 체로 체질 된 경우 실행 시간은 nloglogn보다는 n입니다 :

실제로

다음과 같이 나는 더 암시 코드 것 .