Bir olasılığı tam ve hızlı bir şekilde hesaplayın


10

[Bu, bir olasılığı tam olarak hesaplamak için ortak bir sorudur ]

Bu görev, bir olasılığı tam ve hızlı bir şekilde hesaplamak için kod yazmakla ilgilidir . Çıktı, en düşük biçimde kesir olarak yazılan kesin bir olasılık olmalıdır. Asla çıktı almamalı, daha 4/8doğrusu 1/2.

Bazı pozitif tamsayılar için n, 1s ve -1s uzunlukta eşit rastgele bir dize düşünün ve A olarak nadlandırın. Şimdi Ailk değerine bitiştirin . Yani A[1] = A[n+1]1'den indeksleme eğer Aşimdi uzunluğa sahiptir n+1. Şimdi n, ilk ndeğerleri her biri 1 / 4,1 / 2, 1/4 olasılıkla -1, 0 veya 1 olan ikinci bir rastgele uzunluk dizesini düşünün ve B olarak adlandırın.

Şimdi iç ürünü incelemek A[1,...,n]ve Bve iç ürünü A[2,...,n+1]ve B.

Örneğin, düşünün n=3. İçin olası değerler Ave Bolabilir A = [-1,1,1,-1]ve B=[0,1,-1]. Bu durumda iki iç ürün 0ve şeklindedir 2.

Kodunuz, her iki iç ürünün de sıfır olma olasılığını vermelidir.

Martin Büttner tarafından üretilen tabloyu kopyalarken aşağıdaki örnek sonuçlara sahibiz.

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

Diller ve kütüphaneler

Ücretsiz olarak istediğiniz dil ve kütüphaneleri kullanabilirsiniz. Kodunuzu çalıştırmak mümkün olmalıdır bu yüzden mümkün olduğunca linux kodunu çalıştırmak / derlemek için tam bir açıklama ekleyin.

Görev

Kodunuz n=1her bir artan n için ayrı bir satırda başlamalı ve doğru çıktıyı vermelidir. 10 saniye sonra durmalıdır.

Puan

Skor, nbilgisayarımda çalıştırıldığında 10 saniye sonra kodunuz durmadan önce ulaşılan en yüksek değerdir. Beraberlik varsa, kazanan en yüksek puana en çabuk ulaşan kişi olacaktır.

Girişler tablosu

  • n = 64içinde Python . Sürüm 1 - Mitch Schwartz
  • n = 106içinde Python . 11 Haziran 2015 Mitch Schwartz
  • n = 151içerisinde C ++ . Mitch Schwartz Limanı'nın cevbyfan64sos cevabı
  • n = 165içinde Python . Sürüm 11 Haziran 2015 Mitch Schwartz ile "budama" versiyonu N_MAX = 165.
  • n = 945içinde Python Min_25 ile tam bir formül kullanılarak. İnanılmaz!
  • n = 1228içinde Python Mitch Schwartz tarafından (Min_25 önceki bir yanıta bağlı) Başka bir kesin formülü kullanarak.
  • n = 2761içinde Python Mitch Schwartz tarafından tamamen aynı formülün daha hızlı bir uygulamasını kullanarak.
  • n = 3250içinde Python kullanarak PYPY aynı uygulamayı kullanarak Mitch Schwartz tarafından. Bu puan pypy MitchSchwartz-faster.py |tail, konsolun yukarıdan aşağı kaymasını önlemelidir.

Ben bir numpy çözüm Boost C ++ daha hızlı çalışıp çalışmadığını merak ediyorum?
qwr

@qwr Bence numpy, numba ve cython Python ailesi içinde tuttukları için ilginç olurdu.

2
Bu en hızlı kod sorunlarından daha fazlasını görmek isterim
qwr

@ qwr bu benim en sevdiğim soru ... Teşekkürler! Buradaki zorluk, bulabileceğiniz en düşük seviye dilde tam olarak aynı algoritmayı kodlamayı içermeyen bir tane bulmaktır.

Sonuçları konsola mı yoksa bir dosyaya mı yazıyorsunuz? Pypy kullanmak ve bir dosyaya yazmak benim için en hızlı görünüyor. Konsol süreci önemli ölçüde yavaşlatır.
gnibbler

Yanıtlar:


24

piton

Bir kapalı form formül p(n)IS

resim açıklamasını buraya girin

Bir üstel üreten fonksiyon p(n)IS

resim açıklamasını buraya girin

I_0(x)birinci türün değiştirilmiş Bessel işlevi nerede .

2015-06-11 tarihinde düzenleyin:
- Python kodunu güncelledi.

2015-06-13 tarihinde düzenleyin:
- yukarıdaki formülün bir kanıtı eklendi.
- düzeltildi time_limit.
- bir PARI / GP kodu ekledi.

piton

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()

PARI / GP

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

İspat:
Bu problem 2 boyutlu (sınırlı) rastgele yürüme problemine benzer.

Eğer A[i] = A[i+1], [1 yol], [2 yol] veya [1 yol] ' (x, y)a geçebiliriz .(x+1, y+1)(x, y)(x-1, y-1)

Eğer A[i] != A[i+1], [1 yol], [2 yol] veya [1 yol] ' (x, y)a geçebiliriz .(x-1, y+1)(x, y)(x+1, y-1)

Let a(n, m) = [x^m]((x+1)^n + (x-1)^n), b(n) = [x^n](1+x)^{2n}ve c(n)hareket yolları sayı (0, 0)için (0, 0)olan nadımlar.

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

Çünkü p(n) = c(n) / 8^n, yukarıdaki kapalı form formülünü alabiliriz.


1
Bu .. iyi .. inanılmaz! Tam formülü nasıl hesapladınız?

1
Vaov! Kapalı form her zaman temizdir!
qwr

1
@Lembik: (Kaba) bir kanıt ekledim.
az

1
@ qwr: Teşekkürler. Ben de öyle düşünüyorum !
az

1
@ mbomb007: Evet. Ancak, bilgi işlem görevinden ziyade bir uygulama görevidir. Yani, ben C ++ kodlamak olmaz.
Min_25

9

piton

Not: Kapalı formlu bir çözüm bulmak için Min_25'i tebrik ediyoruz!

İlginç sorun için teşekkürler! Şu anda daha yüksek bir skor elde etmek için hızı optimize etmek için çok motive olmama rağmen, DP kullanarak çözülebilir. Golf için güzel olabilir.

N=39Python 2.7.5 çalıştıran bu eski dizüstü bilgisayarda kod 10 saniye içinde ulaştı .

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

Başlığın için (a,b,s,t): abirinci elemandır A, bson elemanıdır B, siç ürünü olan A[:-1]ve Bve tiç ürünüdür A[1:-1]ve B[:-1]Python dilim gösterimini kullanarak. Kodum dizileri Aveya Bherhangi bir yerde saklamaz , bu yüzden sırasıyla Ave eklenecek sonraki öğelere başvurmak için bu harfleri kullanın B. Bu değişken adlandırma seçeneği, açıklamayı biraz garip hale getirir, ancak A*b+a*Bkodun kendisinin hoş görünmesini sağlar . ASon öğe her zaman ilk öğe ile aynı olduğundan, eklenen öğenin sondan bir önceki öğeye dikkat edin. Ben dahil Martin BÜTTNER en hile kullanmış 0iki kezBuygun olasılık dağılımını elde etmek için adaylar. Sözde X(adı Yverilen N+1), grubun değerine göre olası tüm dizilerin sayısını izler. Değişkenler nve dpay ve payda anlamına gelir, bu yüzden nproblem ifadesini yeniden adlandırdım N.

Mantığın temel kısmı, sadece gruptaki değerleri kullanarak güncellemeyi Nyapabilmenizdir N+1. Soruda belirtilen iki iç ürün s+A*Bve ile verilmiştir t+A*b+a*B. Tanımları biraz incelerseniz bu açıktır; dikkat [A,a]ve [b,B]diziler son iki unsurlarıdır Ave Bsırasıyla.

Not sve tküçük ve uygun sınırlanmış olan Nve hızlı bir dilde bir an önce uygulanması için biz diziler lehine sözlükleri önlemek olabilir.

Sadece işarette farklılık gösteren değerler dikkate alınarak simetriden faydalanmak mümkün olabilir; Buna bakmadım.

Açıklama 1 : Sözlüğün boyutu kuadratik olarak büyür N; burada boyut, anahtar / değer çiftlerinin sayısı anlamına gelir.

Açıklama 2 : Eğer bir üst sınır Nkoyarsak, bunun için N_MAX - N <= |s|ve benzer şekilde tuples budanabiliriz t. Bu emici bir durum belirtilerek veya budanmış durumların sayısını tutmak için örtük bir değişkenle yapılabilir (her yinelemede 8 ile çarpılması gerekir).

Güncelleme : Bu sürüm daha hızlı:

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()

Uygulanan optimizasyonlar:

  • her şeyi içine koyun main()- yerel değişken erişim küreselden daha hızlı
  • idare N=1çek önlemek için açık bir şekilde (1,-1) if N else [a](elemanları eklerken, başlığın ilk eleman tutarlı olduğunu zorlar Aboş liste başlayarak)
  • İç döngüleri açın, bu da çarpmayı ortadan kaldırır
  • sayımını çift cbir ekleme 0için Biki kez bu işlemleri yerine yapıyor
  • payda her zaman 8^Nöyledir , bu yüzden onu takip etmemiz gerekmez
  • Şimdi hesaba simetriyi alarak: Biz ilk elemanını çözebilirsiniz Aolarak 1ve tarafından paydayı bölmek 2geçerli çiftlere beri (A,B)birlikte A[1]=1ve olanlar A[1]=-1olumsuzlaştırılmasıyla bire-bir yazışma içine konabilir A. Benzer şekilde, ilk öğesini Bnegatif olmayan olarak düzeltebiliriz .
  • şimdi budama ile. N_MAXMakinenizde hangi puanı alabileceğini görmek için uğraşmanız gerekir . N_MAXİkili arama ile uygun bir otomatik olarak bulmak yeniden yazılabilir , ancak gereksiz görünüyor mu? Not: Budama koşuluna ulaşana kadar kontrol etmemiz gerekmez N_MAX / 2, bu yüzden iki aşamada tekrarlayarak biraz hızlanabildik, ancak basitlik ve kod temizliği için karar vermemeye karar verdim.

1
Bu gerçekten harika bir cevap! Hızlanmanızda ne yaptığınızı açıklar mısınız?

@Lembik Thank you :) Bir açıklama ve başka bir küçük optimizasyon ekledi ve Python3 uyumlu hale getirdi.
Mitch Schwartz

Bilgisayarımda, N=57ilk sürümü ve N=75ikincisini aldım .
kirbyfan64sos

Cevaplarınız harikaydı. Sadece Min_25'in cevabı daha da

5

piton

Min_25'in rastgele yürüyüş fikrini kullanarak farklı bir formüle ulaşmayı başardım:

p (n) = \ başlangıç ​​{durumlar} \ frac {\ sum _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {tek} \ \ frac {\ binom {n} {n / 2} ^ 2 + \ toplam _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {çift} \ \ end {cases}

İşte Min_25 tabanlı bir Python uygulaması:

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çıklama / kanıt:

İlk olarak, izin verdiğimiz ilgili bir sayım problemini çözüyoruz A[n+1] = -A[1]; yani, birleştirilen ek öğe , ilk öğe Aolabilir 1veya -1ne olursa olsun. Bu yüzden kaç kez A[i] = A[i+1]meydana geldiğini takip etmemize gerek yok . Aşağıdaki rastgele yürüyüşümüz var:

Dan (x,y)biz taşıyabilirsiniz (x+1,y+1)[1 arada], (x+1,y-1)[1 yolu], (x-1,y+1)[1 yolu], (x-1,y-1)[1 yolu], (x,y)[4 yolu]

nerede xve yiki nokta ürünleri için durmak ve biz yolları sayısı taşınmaya güveniyoruz (0,0)için (0,0)de nadımlar. Bu sayı daha sonra veya ile başlayabilen 2gerçeği hesaba katarak çarpılır .A1-1

Biz de kaldıkları ifade (x,y)bir şekilde sıfır hareket .

iGeri dönmek için bile olması gereken sıfır olmayan hareketlerin sayısını yineliyoruz (0,0). Yatay ve dikey hareketler , binom katsayısının C(i,i/2)^2olduğu sayılabilecek iki bağımsız tek boyutlu rastgele yürüyüş oluşturur C(n,k). ( kAdımlar sol ve kadımların sağ olduğu bir yürüyüş için, adımların C(2k,k)sırasını C(n,i)seçmenin yolları vardır.) Ek olarak , hareketleri yerleştirmenin 4^(n-i)yolları ve sıfır hareketleri seçmenin yolları vardır. Yani şunu elde ederiz:

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

Şimdi, orijinal soruna geri dönmeliyiz. Kabul edilebilir bir çift tanımlama (A,B)için dönüştürülebilir ise B, bir sıfır içerir. Bir çift tanımlayın (A,B)olmak neredeyse izin verilebilir eğer A[n+1] = -A[1]iki nokta ürünler her ikisi sıfırdır.

Lemma: Belirli bir durumda n, neredeyse izin verilen çiftler, dönüştürülebilir çiftlerle birebir yazışmalar içindedir.

Biz (tersinir) dönüştürülebilir bir çifti dönüştürebilirsiniz (A,B)neredeyse izin verilen çiftine (A',B')olumsuzlaştırılmasıyla A[m+1:]ve B[m+1:]nerede mson sıfır endeksidir B. Bunun kontrolü basittir: Eğer son öğesi Bsıfır ise, hiçbir şey yapmamız gerekmez. Aksi takdirde, son elemanını Areddettiğimizde B, kaydırılan nokta ürününün son terimini korumak için son elemanını reddedebiliriz . Ancak bu, kaydırılmamış nokta ürününün son değerini reddeder, bu yüzden bunu ikinci ila son öğesini reddederek düzeltiriz A. Ancak daha sonra bu, kaydırılan ürünün ikinci-son değerini atar, bu yüzden ikinci-son öğesini reddederiz B. Ve böylece, sıfır elemente ulaşana kadar B.

Şimdi, Bsıfır içermeyen neredeyse izin verilen çiftlerin olmadığını göstermemiz gerekiyor . Bir nokta ürününün sıfıra eşit olması için , iptal etmek için eşit sayıda 1ve -1terime sahip olmamız gerekir . Her -1terim (1,-1)veya öğesinden oluşur (-1,1). Böylece -1meydana gelen sayının paritesi sabittir n. İlk ve son unsurlarının Afarklı işaretleri varsa, pariteyi değiştiririz, bu yüzden bu imkansızdır.

Böylece biz

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

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

yukarıdaki formülü verir (ile yeniden indeksleme i' = i/2).

Güncelleme: İşte aynı formülü kullanan daha hızlı bir sürüm:

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()

Uygulanan optimizasyonlar:

  • satır içi işlev p(n)
  • binom katsayıları için tekrarını kullanmak C(n,k)ilek <= n/2
  • merkezi binom katsayıları için nüks kullanın

Bildiğiniz gibi, p(n)parçalı bir işlev olması gerekmez. Genel olarak, bunun yerine f(n) == {g(n) : n is odd; h(n) : n is even}yazabilir f(n) == (n-2*floor(n/2))*g(n) + ((n+1)-2*(floor((n+1)/2)))*h(n)veya kullanabilirsiniz . Buraya bakınn mod 2(n-2*floor(n/2))
mbomb007

1
@ mbomb007 Bu çok açık ve ilgisiz.
Mitch Schwartz

3

Min_25 formülünün açıklaması

Min_25 harika bir kanıt yayınladı, ancak takip edilmesi biraz zaman aldı. Bu, satırlar arasında doldurulması gereken bir açıklamadır.

a (n, m), A [i] = A [i + 1] m kez olacak şekilde A seçmenin yol sayısını temsil eder. Bir (n, m) formülü, nm için bile bir (n, m) = {2 * (n, m'yi seçer) ile eşdeğerdir; Nm tek oranı için 0} A [i]! = A [i + 1] eşit sayıda kez oluşmalıdır çünkü A [0] = A [n]. 2 faktörü başlangıçtaki A [0] = 1 veya A [0] = -1 seçiminden kaynaklanmaktadır.

(A [i]! = A [i + 1]) sayısı q (c (n) formülünde i olarak adlandırılır) olarak sabitlendiğinde, q ve nq uzunluğunda iki adet 1D rastgele yürüyüşe ayrılır. b (m), başladığı yerde biten ve% 25 sola hareket etme şansı,% 50 hareketsiz kalma şansı ve% 25 kalma şansına sahip m adımlardan tek boyutlu rastgele bir yürüyüş yapmanın yol sayısıdır. sağa hareket ediyor. Oluşturma işlevini belirtmenin daha açık bir yolu [x ^ m] (1 + 2x + x ^ 2) ^ n'dir; burada 1, 2x ve x ^ 2 sırasıyla sola, hareketsiz ve sağa karşılık gelir. Ama sonra 1 + 2x + x ^ 2 = (x + 1) ^ 2.


PPCG'yi sevmenin bir başka nedeni! Teşekkür ederim.

2

C ++

Mitch Schwartz'ın (mükemmel) Python cevabının sadece bir limanı. En önemli fark kullandığım olmasıdır 2temsil etmek -1için adeğişken ve benzer bir şey yaptı bbana bir dizi kullanmak için izin. Intel C ++ kullanarak -O3, bende N=141! İlk versiyonum var N=140.

Bu Boost kullanır. Paralel bir versiyon denedim ama bazı sıkıntılarla karşılaştım.

#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;
}

Bunun g++ -O3 kirbyfan64sos.cpp -o kirbyfan64sos -lboost_system -lboost_timer -lboost_chrono -lrt -lgmpderlenmesi gerekiyor . (Aditsu'ya teşekkürler.)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.