정확하고 신속하게 확률 계산


10

[ 확률을 정확하게 계산하기 위한 파트너 질문입니다 ]

이 작업은 확률을 정확 하고 신속하게 계산하기위한 코드 작성에 관한 것입니다 . 결과는 가장 축소 된 형태로 분수로 쓰여진 정확한 확률이어야합니다. 즉, 출력 4/8하지 말고 오히려 출력해야합니다 1/2.

양의 정수의 경우 n, 길이가 1과 -1 인 균일하게 임의의 문자열을 고려하여 nA라고 부릅니다. 이제 A첫 번째 값으로 연결 합니다. 즉 A[1] = A[n+1](1)에서 색인 경우 A지금 길이 n+1. 이제 n첫 번째 n값이 각각 1 / 4,1 / 2, 1/4 인 -1, 0 또는 1 인 길이 의 두 번째 임의의 문자열을 고려하여 B라고 부릅니다.

지금의 내적 생각 A[1,...,n]B와의 내적을 A[2,...,n+1]하고 B.

예를 들어을 고려하십시오 n=3. 가능한 값 ABA = [-1,1,1,-1]B=[0,1,-1]. 이 경우 두 개의 내부 제품은 02입니다.

코드는 두 내부 제품이 모두 0 일 확률을 출력해야합니다.

Martin Büttner가 생산 한 표를 복사하면 다음과 같은 샘플 결과가 나타납니다.

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

언어와 라이브러리

원하는 언어와 라이브러리를 자유롭게 사용할 수 있습니다. 코드를 실행할 수 있어야하므로 가능한 경우 리눅스에서 코드를 실행 / 컴파일하는 방법에 대한 자세한 설명을 포함하십시오.

작업

코드는 시작 n=1하여 별도의 줄에 증가하는 각 n에 대해 올바른 출력을 제공 해야합니다 . 10 초 후에 중지해야합니다.

점수

점수는 단순히 n컴퓨터에서 실행될 때 10 초 후에 코드가 중지되기 전에 도달 한 최고 점수입니다 . 동점이 있다면, 가장 높은 점수를 얻는 사람이 승자가됩니다.

항목 표

  • n = 64에서 파이썬 . Mitch Schwartz의 버전 1
  • n = 106에서 파이썬 . Mitch Schwartz의 2015 년 6 월 11 일 버전
  • n = 151에서 C ++ . kirbyfan64sos의 미치 슈워츠 항 답변
  • n = 165에서 파이썬 . 2015 년 6 월 11 일 Mitch Schwartz의 "정리"버전 N_MAX = 165.
  • n = 945정확한 공식을 사용하여 Min_25에 의해 Python 에서 . 놀랄 만한!
  • n = 1228파이썬 미치 슈워츠 (Min_25의 이전 답변에 따라) 다른 정확한 공식을 사용하여.
  • n = 2761파이썬 미치 슈워츠에 의해 똑같은 식의 빠른 구현을 사용.
  • n = 3250에서 파이썬 사용 Pypy를 같은 구현을 사용 미치 슈워츠에 의해. 이 점수는 pypy MitchSchwartz-faster.py |tail콘솔 스크롤 오버 헤드를 피해야합니다.

numpy 솔루션이 Boost C ++보다 빠르게 실행 될지 궁금합니다.
qwr

@ qwr numpy, numba 및 cython은 Python 제품군 내에서 유지 될 때 모두 흥미로울 것이라고 생각합니다.

2
이 가장 빠른 코드 문제를 더보고 싶습니다
qwr

@qwr 가장 좋아하는 질문입니다 ... 감사합니다! 문제는 찾을 수있는 가장 낮은 수준의 언어로 정확히 동일한 알고리즘을 코딩하지 않는 것을 찾는 것입니다.

콘솔이나 파일에 결과를 쓰고 있습니까? pypy를 사용하고 파일에 쓰는 것이 가장 빠릅니다. 콘솔은 프로세스 속도를 상당히 느리게합니다.
gnibbler 2016 년

답변:


24

파이썬

닫힌 형식의 공식 p(n)

여기에 이미지 설명을 입력하십시오

의 지수 생성 함수 p(n)

여기에 이미지 설명을 입력하십시오

I_0(x)첫 번째 종류의 수정 된 Bessel 함수는 어디에 있습니까 ?

2015-06-11 편집 :
-Python 코드가 업데이트되었습니다.

2015-06-13 편집 :
-위 공식의 증거를 추가했습니다.
-고정 time_limit.
-PARI / GP 코드가 추가되었습니다.

파이썬

def solve():
  # straightforward implementation

  from time import time
  from itertools import count

  def binom(n, r):
    return facts[n] // (facts[r] * facts[n - r])

  def p(N):
    ans = 0
    for i in range(1 + N // 2):
      t = binom(2 * (N - 2 * i), N - 2 * i)
      t *= binom(N, 2 * i)
      t *= binom(4 * i, 2 * i)
      ans += t
    e = (ans & -ans).bit_length() - 1
    numer = ans >> e
    denom = 1 << (3 * N - 1 - e)
    return numer, denom

  facts = [1]
  time_limit = 10.0 + time()

  for i in count(1):
    facts.append(facts[-1] * (2 * i - 1))
    facts.append(facts[-1] * (2 * i))

    n, d = p(i)

    if time() > time_limit:
      break

    print("%d %d/%d" % (i, n, d))

solve()

파리 / GP

p(n) = polcoeff( (exp(x/2) + 1) * besseli(0, x/4) ^ 2, n) * n!;

증명 :
이 문제는 2 차원 (제한된) 임의 걷기 문제와 유사합니다.

경우 A[i] = A[i+1], 우리는 이동할 수 (x, y)(x+1, y+1)[1 개 방법], (x, y)[2 가지 방법] 또는 (x-1, y-1)[1 개 방법].

경우 A[i] != A[i+1], 우리는 이동할 수 (x, y)(x-1, y+1)[1 개 방법], (x, y)[2 가지 방법] 또는 (x+1, y-1)[1 개 방법].

하자 a(n, m) = [x^m]((x+1)^n + (x-1)^n), b(n) = [x^n](1+x)^{2n}c(n)이동할 수있는 방법의 숫자 (0, 0)(0, 0)n단계.

그때, c(n) = \sum_{i=0}^n a(n, i) * b(i) * b(n-i).

이므로 p(n) = c(n) / 8^n위의 닫힌 형식 수식을 얻을 수 있습니다.


1
이것은 .. 잘 .. 훌륭합니다! 지구상에서 정확한 공식을 어떻게 계산 했습니까?

1
와! 닫힌 형태는 항상 깔끔합니다!
qwr

1
@Lembik : 나는 (거친) 증거를 추가했습니다.
Min_25

1
@qwr : 감사합니다. 나도 그렇게 생각해 !
Min_25

1
@ mbomb007 : 그렇습니다. 그러나 이는 컴퓨팅 작업이 아닌 구현 작업입니다. 따라서 C ++로 코딩하지 않습니다.
Min_25

9

파이썬

참고 : 비공개 솔루션을 찾아서 Min_25를 축하합니다!

흥미로운 문제에 감사드립니다! DP를 사용하여 해결할 수는 있지만 현재 높은 점수를 얻기 위해 속도를 최적화하려는 동기는별로 없습니다. 골프에 좋습니다.

N=39Python 2.7.5를 실행하는이 오래된 랩톱에서 코드가 10 초 내에 도달했습니다 .

from time import*
from fractions import*
from collections import*

X={(1,0,0,0):1,(-1,0,0,0):1}

T=time()
N=0

while 1:
    Y=defaultdict(lambda:0)
    n=d=0
    for a,b,s,t in X:
        c=X[(a,b,s,t)]
        for A in ( (1,-1) if N else [a] ):
            for B in 1,0,0,-1:
                n+=c*(s+A*B==0==t+A*b+a*B)
                d+=c
                Y[(a,B,s+A*B,t+A*b)]+=c
    if time()>T+10: break
    N+=1
    print N,Fraction(n,d)
    X=Y

튜플 (a,b,s,t): a의 첫번째 원소이며 A, b마지막 요소 인 B, s의 내적이다 A[:-1]하고 B, 그리고 t내부의 제품 A[1:-1]B[:-1]파이썬 슬라이스 표기법. 내 코드는 배열을 저장하지 않습니다 A또는 B내가에 추가 할 다음 요소를 참조하는 문자를 사용하므로, 어느 곳 AB각각. 이 변수 이름 지정을 선택하면 설명이 약간 어색하지만 A*b+a*B코드 자체를 멋지게 볼 수 있습니다. A마지막 요소는 항상 첫 번째 요소와 동일하므로 추가되는 요소 는 두 번째 요소입니다. 나는 Martin Büttner의 트릭을 0두 번 포함시키는 데 사용 했습니다.B적절한 확률 분포를 얻기 위해 후보. 사전 X(라는 Y위해는 N+1) 튜플의 값에 따라 모든 가능한 배열의 카운트 값 유지한다. 변수 nd분자 및 분모를 n나타내므로 문제 설명의 이름을로 변경 했습니다 N.

논리의 핵심 부분은 당신이에서 업데이트 할 수 있습니다 NN+1튜플에서 바로 값을 사용. 질문에 지정된 두 가지 내부 제품은 s+A*B및 로 제공됩니다 t+A*b+a*B. 정의를 약간 살펴보면 분명히 알 수 있습니다. 점에 유의 [A,a]하고 [b,B]배열의 마지막 두 요소 AB각각은.

st소형에 따라 묶여 있습니다 N, 그리고 빠른 언어의 빠른 구현을 위해 우리가 배열에 찬성 사전을 피할 수 있습니다.

부호 만 다른 값을 고려하여 대칭을 활용할 수 있습니다. 나는 그것을 조사하지 않았습니다.

비고 1 : 사전의 크기는에서 2 차적으로 증가합니다 N. 여기서 크기는 키-값 쌍의 수를 의미합니다.

2두기 : 우리가 상단에 바인딩 설정하면 N되는, 우리는 가지 치기 할 수 튜플 N_MAX - N <= |s|유사 위해 t. 이는 흡수 상태를 지정하거나 프 루닝 된 상태 수 (각 반복마다 8을 곱해야 함)를 보유 할 변수를 내재적으로 지정하여 수행 할 수 있습니다.

업데이트 :이 버전이 더 빠릅니다.

from time import*
from fractions import*
from collections import*

N_MAX=115

def main():
    T=time()

    N=1
    Y={(1,0,0,0):1,(1,1,1,0):1}
    n=1
    thresh=N_MAX

    while time() <= T+10:
        print('%d %s'%(N,Fraction(n,8**N/4)))

        N+=1
        X=Y
        Y=defaultdict(lambda:0)
        n=0

        if thresh<2:
            print('reached MAX_N with %.2f seconds remaining'%(T+10-time()))
            return

        for a,b,s,t in X:
            if not abs(s)<thresh>=abs(t):
                continue

            c=X[(a,b,s,t)]

            # 1,1

            if not s+1 and not t+b+a: n+=c
            Y[(a,1,s+1,t+b)]+=c

            # -1,1

            if not s-1 and not t-b+a: n+=c
            Y[(a,1,s-1,t-b)]+=c

            # 1,-1

            if not s-1 and not t+b-a: n+=c
            Y[(a,-1,s-1,t+b)]+=c

            # -1,-1

            if not s+1 and not t-b-a: n+=c
            Y[(a,-1,s+1,t-b)]+=c

            # 1,0

            c+=c

            if not s and not t+b: n+=c
            Y[(a,0,s,t+b)]+=c

            # -1,0

            if not s and not t-b: n+=c
            Y[(a,0,s,t-b)]+=c

        thresh-=1

main()

최적화 구현 :

  • 에 넣어 모든 main()- 지역 변수 액세스 빠른 글로벌보다
  • N=1검사를 피하기 위해 명시 적으로 처리 하십시오 (1,-1) if N else [a]( A빈 목록에서 시작 하여 요소를 추가 할 때 튜플의 첫 번째 요소가 일관되도록 합니다)
  • 내부 루프를 풀면 곱셈이 제거됩니다.
  • 수를 두 배로 c을 추가 0B두 번 그 작업을 대신하고
  • 분모는 항상 8^N그래서 우리는 그것을 추적 할 필요가 없습니다
  • 이제 대칭을 고려 : Aas 의 첫 번째 요소를 고치고 1분모를 나눌 수 있습니다 2. 유효한 쌍 (A,B)A[1]=1를 가진 쌍 A[1]=-1은 부정함으로써 일대일 대응이 가능하기 때문 A입니다. 마찬가지로 첫 번째 요소를 B음이 아닌 것으로 고칠 수 있습니다 .
  • 이제 가지 치기와 함께. 당신은 N_MAX당신의 컴퓨터에 어떤 점수를 얻을 수있는 바이올린 을해야합니다. N_MAX이진 검색을 통해 자동으로 적절한 것을 찾도록 다시 작성할 수는 있지만 불필요한 것 같습니다. 참고 : 우리는 주변 N_MAX / 2에 도달 할 때까지 가지 치기 조건을 확인할 필요가 없으므로 두 단계로 반복하여 약간의 속도를 높일 수 있지만 단순성과 코드 청결도를 결정하지 않았습니다.

1
이것은 정말 좋은 답변입니다! 당신의 속도 향상에 대해 설명해 주시겠습니까?

@Lembik Thank you :) 설명과 함께 작은 최적화를 추가하고 Python3과 호환되도록 만들었습니다.
Mitch Schwartz

내 컴퓨터 N=57에는 첫 번째 버전과 N=75두 번째 버전이 있습니다.
kirbyfan64sos 2016 년

당신의 대답은 굉장했습니다. 단지 Min_25의 답변이 훨씬 더 그렇습니다. :)

5

파이썬

랜덤 워크에 대한 Min_25의 아이디어를 사용하여 다른 공식에 도달 할 수있었습니다.

p (n) = \ begin {cases} \ frac {\ sum _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {odd} \ \ fra {{binom {n} {n / 2} ^ 2 + \ sum _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {짝수} \ \ end {cases}

Min_25를 기반으로 한 Python 구현은 다음과 같습니다.

from time import*
from itertools import*

def main():
    def binom(n, k):
        return facts[n]/(facts[k]*facts[n-k])

    def p(n):
        numer=0
        for i in range(n/2+1):
            t=binom(2*i,i)
            t*=t
            t*=binom(n,2*i)
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)
        return numer, denom

    facts=[1]
    time_limit=time()+10

    for i in count(1):
        facts.append(facts[-1]*i)

        n,d=p(i)

        if time()>time_limit:
            break

        print("%d %d/%d"%(i,n,d))

main()

설명 / 증거 :

먼저 관련된 계산 문제를 해결합니다 A[n+1] = -A[1]. 즉, 연결되는 추가 요소 는 첫 번째 요소에 관계없이 또는 상관없이 A가능합니다 . 따라서 몇 번 발생 했는지 추적 할 필요가 없습니다 . 우리는 다음과 같은 무작위 산책을했습니다.1-1A[i] = A[i+1]

에서 (x,y)우리는 이동할 수 있습니다 (x+1,y+1)[1 개 방법], (x+1,y-1)[1 방법], (x-1,y+1)[1 개 방법], (x-1,y-1)[1 개 방법], (x,y)[4 가지 방법]

경우 xy두 점의 제품 서, 우리는 방법의 수에서 이동 계산됩니다 (0,0)(0,0)n단계. 그런 다음 또는로 시작할 수 2있는 사실을 설명하기 위해이 수를 곱합니다 .A1-1

우리 (x,y)제로 이동 을 유지하는 것을 말합니다 .

우리는 0이 아닌 움직임의 수를 반복 i합니다 (0,0). 수평 및 수직 이동은 2 개의 독립적 인 1 차원 무작위 보행을 구성하며 C(i,i/2)^2, C(n,k)이항 계수는 로 계산할 수 있습니다 . ( k왼쪽과 k오른쪽 으로 단계가 있는 걷기 C(2k,k)의 경우 단계 순서를 선택하는 방법이 있습니다.) 또한 C(n,i)움직임을 배치하는 4^(n-i)방법 과 제로 움직임을 선택하는 방법이 있습니다. 그래서 우리는 얻는다 :

a(n) = 2 * sum_{i in (0,2,4,...,n)} C(i/2,i)^2 * C(n,i) * 4^(n-i)

이제 원래 문제로 되돌려 야합니다. 허용되는 쌍이 0을 포함하는 경우 변환 가능 (A,B)하도록 정의하십시오 . 두 도트 곱이 모두 0 인 경우 거의 허용 되는 쌍 을 정의하십시오 .B(A,B)A[n+1] = -A[1]

렘마 : 주어진의 n경우, 거의 허용되는 쌍은 컨버터블 쌍과 일대일로 일치합니다.

우리는 (가역적) 컨버터블 쌍을 변환 할 수 있습니다 (A,B)거의 허용 쌍에 (A',B')부정으로 A[m+1:]하고 B[m+1:], 어디 m에서 마지막 제로의 인덱스입니다 B. 이것에 대한 점검은 간단합니다. 마지막 요소 B가 0이면 아무것도 할 필요가 없습니다. 그렇지 않으면의 마지막 요소를 무효화 할 때 이동 된 내적의 마지막 항을 보존하기 위해 A의 마지막 요소를 무효화 할 수 있습니다 B. 그러나 이것은 쉬프트되지 않은 내적의 최종 값을 무효화하므로 우리는의 두 번째-마지막 요소를 무효화하여이를 수정합니다 A. 그러나 이것은 시프트 된 제품의 마지막에서 마지막까지의 가치를 버리므로 두 번째에서 마지막까지의 요소를 무시합니다 B. 그리고에서 0 요소에 도달 할 때까지 계속됩니다 B.

이제 우리 B는 0을 포함하지 않는 거의 허용 가능한 쌍이 없음을 보여 주면 됩니다. 내적이 0이되도록 하려면 취소 할 수 1-1항이 같아야 합니다. 각 -1용어는 (1,-1)또는 로 구성 (-1,1)됩니다. 따라서 -1발생 하는 수의 패리티는 에 따라 고정됩니다 n. 첫 번째 요소와 마지막 요소에 A서로 다른 부호가 있으면 패리티가 변경되므로 불가능합니다.

그래서 우리는

c(n) = a(n)/2 if n is odd, else a(n)/2 + C(n,n/2)^2

p(n) = c(n) / 8^n

위의 수식을 제공합니다 (로 다시 색인 생성 i' = i/2).

업데이트 : 다음은 동일한 수식을 사용하는 더 빠른 버전입니다.

from time import*
from itertools import*

def main():
    time_limit=time()+10

    binoms=[1]
    cb2s=[1]
    cb=1

    for n in count(1):
        if n&1:
            binoms=[a+b for a,b in zip([0]+binoms,binoms)]
        else:
            binoms=[a+b for a,b in zip([0]+binoms,binoms+[binoms[-1]])]
            cb=(cb<<2)-(cb+cb)/(n/2)
            cb2s.append(cb*cb)

        numer=0
        for i in xrange(n/2+1):
            t=cb2s[i]*binoms[min(2*i,n-2*i)]
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)

        if time()>time_limit:
            break

        print("%d %d/%d"%(n,numer,denom))

main()

최적화 구현 :

  • 인라인 함수 p(n)
  • 이항 계수에 대한 재발을 사용 C(n,k)하여k <= n/2
  • 중심 이항 계수에 대해 반복 사용

아시다시피, 부분 p(n)적인 함수일 필요는 없습니다. 일반적으로 f(n) == {g(n) : n is odd; h(n) : n is even}그렇다면 대신 대신 f(n) == (n-2*floor(n/2))*g(n) + ((n+1)-2*(floor((n+1)/2)))*h(n)쓰거나 사용할 수 있습니다 . 여기를 참조 하십시오n mod 2(n-2*floor(n/2))
mbomb007

1
@ mbomb007 그것은 분명하고 흥미롭지 않습니다.
Mitch Schwartz

3

Min_25의 수식에 대한 설명

Min_25는 훌륭한 증거를 게시했지만 시간이 오래 걸렸습니다. 이것은 선 사이를 채우는 약간의 설명입니다.

a (n, m)은 A [i] = A [i + 1] m 배가되도록 A를 선택하는 방법의 수를 나타냅니다. a (n, m)의 공식은 nm 짝수의 경우 a (n, m) = {2 * (n은 m을 선택)와 같습니다. nm odd의 경우 0입니다.} A [i]! = A [i + 1]은 짝수 번 발생해야 A [0] = A [n]이므로 하나의 패리티 만 허용됩니다. 2의 요인은 초기 선택 A [0] = 1 또는 A [0] = -1 때문입니다.

(A [i]! = A [i + 1])의 수가 q (c (n) 공식에서 i로 명명 됨)로 고정되면, 길이 q와 nq의 2 개의 1D 랜덤 보행으로 분리됩니다. b (m)은 시작한 곳에서 끝나고 25 %의 왼쪽 이동 확률, 50 %의 정지 가능성 및 25 %의 확률을 갖는 m 단계의 1 차원 랜덤 보행을 수행하는 방법의 수입니다. 오른쪽으로 이동 생성 함수를 명시하는보다 확실한 방법은 [x ^ m] (1 + 2x + x ^ 2) ^ n입니다. 여기서 1, 2x 및 x ^ 2는 각각 왼쪽, 이동 없음 및 오른쪽을 나타냅니다. 그러나 1 + 2x + x ^ 2 = (x + 1) ^ 2입니다.


PPCG를 사랑해야 할 또 다른 이유! 감사합니다.

2

C ++

Mitch Schwartz의 (우수한) Python 답변 포트. 가장 큰 차이점은 내가 사용하는 것입니다 2나타내는 -1에 대한 a변수에 대한 비슷한했던 b나 배열을 사용할 수 있도록 허용. 인텔 C ++를 사용하여 -O3, 내가 있어요 N=141! 내 첫 번째 버전이 N=140있습니다.

이것은 Boost를 사용합니다. 병렬 버전을 시도했지만 문제가 발생했습니다.

#include <boost/multiprecision/gmp.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/rational.hpp>
#include <boost/chrono.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <utility>
#include <map>

typedef boost::multiprecision::mpz_int integer;
typedef boost::array<boost::array<std::map<int, std::map<int, integer> >, 3>, 2> array;
typedef boost::rational<integer> rational;

int main() {
    BOOST_AUTO(T, boost::chrono::high_resolution_clock::now());

    int N = 1;
    integer n = 1;
    array* Y = new array, *X = NULL;
    (*Y)[1][0][0][0] = 1;
    (*Y)[1][1][1][0] = 1;

    while (boost::chrono::high_resolution_clock::now() < T+boost::chrono::seconds(10)) {
        std::cout << N << " " << rational(n, boost::multiprecision::pow(integer(8), N)/4) << std::endl;
        ++N;
        delete X;
        X = Y;
        Y = new array;
        n = 0;

        for (int a=0; a<2; ++a)
            for (int b=0; b<3; ++b)
                for (BOOST_AUTO(s, (*X)[a][b].begin()); s != (*X)[a][b].end(); ++s)
                    for (BOOST_AUTO(t, s->second.begin()); t != s->second.end(); ++t) {
                        integer c = t->second;
                        int d = b&2 ? -1 : b, e = a == 0 ? -1 : a;

                        if (s->first == -1 && t->first+d+e == 0) n += c;
                        (*Y)[a][1][s->first+1][t->first+d] += c;

                        if (s->first == 1 && t->first-d+e == 0) n += c;
                        (*Y)[a][1][s->first-1][t->first-d] += c;

                        if (s->first == 1 && t->first+d-e == 0) n += c;
                        (*Y)[a][2][s->first-1][t->first+d] += c;

                        if (s->first == -1 && t->first-d-e == 0) n += c;
                        (*Y)[a][2][s->first+1][t->first-d] += c;

                        c *= 2;

                        if (s->first == 0 && t->first+d == 0) n += c;
                        (*Y)[a][0][s->first][t->first+d] += c;

                        if (s->first == 0 && t->first-d == 0) n += c;
                        (*Y)[a][0][s->first][t->first-d] += c;
                    }
    }

    delete X;
    delete Y;
}

g++ -O3 kirbyfan64sos.cpp -o kirbyfan64sos -lboost_system -lboost_timer -lboost_chrono -lrt -lgmp컴파일 해야 합니다. (aditsu에게 감사드립니다.)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.