Kata faktorisasi di


12

Diberikan dua string S1,S2 , kami menulis S1S2 untuk penggabungan mereka. Mengingat string S dan integer k1 , kita menulis (S)k=SSS untuk gabungan dari k salinan S . Sekarang diberi string, kita dapat menggunakan notasi ini untuk 'kompres' itu, yaitu AABAAB dapat ditulis sebagai ((A)2B)2 . Mari kita sebut berat darikompresijumlah karakter yang muncul di dalamnya, sehingga berat((A)2B2) adalah dua, dan berat(AB)2A (akompresidariABABA ) adalah tiga (A terpisah dihitung secara terpisah).

Sekarang pertimbangkan masalah komputasi kompresi 'teringan' dari string S dengan |S|=n . Setelah beberapa pemikiran ada pendekatan pemrograman dinamis yang berjalan di O(n3logn) atau O(n3) tergantung pada pendekatan yang tepat.

Namun, saya telah diberitahu bahwa masalah ini dapat diselesaikan dalam waktu O(n2logn) , meskipun saya tidak dapat menemukan sumber tentang cara melakukan ini. Secara khusus, masalah ini diberikan dalam kontes pemrograman terbaru (masalah K di sini , dua halaman terakhir). Selama analisis sebuah algoritma O(n3logn) disajikan, dan pada akhirnya batas kuadrat semu disebutkan ( di sini pada tanda empat menit). Sayangnya presenter hanya menyebut 'lemma kata kombinatorik yang rumit', jadi sekarang saya datang ke sini untuk meminta solusinya :-)


SS=Xa=YbS=Z|S|/gcd(|X|,|Y|)Zgcd(|X|,|Y|)XYS=XaSYS=Yb, maka Anda hanya perlu mencoba awalan dari memiliki panjang yang membagi. YX|X|
j_random_hacker

Masalahnya adalah bahwa bahkan setelah mengurangi semua kemungkinan , Anda masih perlu menjumlahkan jawabannya dengan DP kubik atas (yaitu ), jadi masih ada beberapa pekerjaan tambahan yang harus dilakukan setelah itu ...XaDP[l,r]=minkDP[l,k]+DP[k+1,r]
Timon Knigge

Saya mengerti apa yang kamu maksud. Saya pikir Anda memerlukan semacam hubungan dominasi yang menghilangkan beberapa nilai dari perlu diuji - tapi saya belum bisa memikirkan satu. Secara khusus, saya mempertimbangkan yang berikut: Misalkan memiliki faktorisasi yang optimal dengan ; apakah mungkin ada solusi optimal di mana difaktorkan sebagai dengan ? Sayangnya jawabannya adalah ya: untuk , memiliki factorisation optimal , tetapi factorisation optimal unik untuk adalah .kS[1..i]S[1..i]=XYkk>1SXYjZj<kS=ABABCABCS[1..4](AB)2SAB(ABC)2
j_random_hacker

Jawaban:


1

Jika saya tidak salah paham dengan Anda, saya pikir faktorisasi biaya minimum dapat dihitung dalam waktu sebagai berikut.O(n2)

Untuk setiap indeks i, kami akan menghitung banyak nilai untuk sebagai berikut. Biarkan menjadi bilangan bulat terkecil sehingga ada bilangan bulat memuaskanUntuk , mari menjadi terbesar dengan properti ini. Jika tidak ada seperti itu, atur sehingga kami tahu ada nilai nol untuk indeks ini.(pi,ri)=1,2,pi11r2

S[irpi1+1,ipi1]=S[i(r1)pi1+1,i].
pi1ri1rpiLi=0(pi,ri)

Biarkan menjadi bilangan bulat terkecil yang benar-benar lebih besar dari memuaskan, demikian juga, untuk beberapa . Seperti sebelumnya, ambil untuk menjadi yang maksimal setelah memperbaiki . Secara umum adalah angka terkecil yang benar-benar lebih besar dari . Jika tidak ada ada, maka .pi2(ri11)pi1

S[iri2pi2+1,ipi2]=S[i(ri21)pi2+1,i]
ri22ri2pi2pi(ri11)pi1piLi=1

Perhatikan bahwa untuk setiap indeks i, kami memiliki karena nilai meningkat secara geometris dengan . (jika ada, itu tidak hanya benar-benar lebih besar dari tetapi lebih besar dari itu dengan setidaknya Ini menetapkan peningkatan geometris. )Li=O(log(i+1))pipi+1(ri1)pipi/2

Misalkan sekarang semua nilai diberikan kepada kami. Biaya minimum diberikan oleh perulangan dengan pemahaman bahwa untuk kita atur . Tabel dapat diisi waktu .(pi,ri)

dp(i,j)=min{dp(i,j1)+1,min(dp(i,jrjpj)+dp(jrjpj+1,jpj))}
i>jdp(i,j)=+O(n2+njLj)

Kami telah mengamati di atas bahwa dengan membatasi jumlah penjumlahan dengan istilah. Tetapi sebenarnya jika kita melihat seluruh jumlah, kita dapat membuktikan sesuatu yang lebih tajam.jLj=O(jlog(j+1))=Θ(nlogn)

Pertimbangkan pohon akhiran dari kebalikan dari (yaitu, pohon awalan S). Kami akan membebankan setiap kontribusi ke jumlah ke tepi sehingga setiap tepi akan dibebankan paling banyak satu kali. Isi daya setiap ke tepi yang berasal dari dan menuju . Di sini adalah daun dari pohon awalan yang bersesuaian dengan dan nca menunjukkan leluhur bersama terdekat.T(S)SiLiT(S)pijnca(v(i),v(ipij))v(ipij)v(i)S[1..i]

Ini menunjukkan bahwa . Nilai-nilai dapat dihitung dalam waktu oleh traversal dari pohon suffix tetapi saya akan meninggalkan detailnya untuk diedit nanti jika ada yang tertarik.O(iLi)=O(n)(pij,rij)O(n+iLi)

Beri tahu saya jika ini masuk akal.


-1

Ada string S panjang awal Anda n. Berikut adalah pseudo-code dari metode ini.

next_end_bracket = n
for i in [0:n]: # main loop

    break if i >= length(S) # due to compression
    w = (next_end_bracket - i)# width to analyse

    for j in [w/2:0:-1]: # period loop, look for largest period first
        for r in [1:n]: # number of repetition loop
            if i+j*(r+1) > w:
                break r loop

            for k in [0:j-i]:
                # compare term to term and break at first difference
                if S[i+k] != S[i+r*j+k]:
                    break r loop

        if r > 1:
            # compress
            replace S[i:i+j*(r+1)] with ( S[i:i+j] )^r
            # don't forget to record end bracket...
            # and reduce w for the i-run, carrying on the j-loop for eventual smaller periods. 
            w = j-i

Saya sengaja memberikan sedikit detail pada "kurung ujung" karena membutuhkan banyak langkah untuk menumpuk dan melepaskan yang akan membuat metode inti tidak jelas. Idenya adalah untuk menguji kontraksi lebih lanjut akhirnya di dalam yang pertama. untuk contoh ABCBCABCBC => (ABCBC) ² => (A (BC) ²) ².

Jadi intinya adalah mencari periode besar dulu. Perhatikan bahwa S [i] adalah istilah ke-S untuk melewatkan "(", ")" atau kekuatan apa pun.

  • i-loop adalah O (n)
  • j-loop adalah O (n)
  • r + k-loop adalah O (log (n)) karena berhenti pada perbedaan pertama

Ini adalah global O (n²log (n)).


Tidak jelas bagi saya bahwa loop r dan k adalah O (log n) - bahkan secara terpisah. Apa yang memastikan bahwa perbedaan ditemukan setelah paling banyak iterasi O (log n)?
j_random_hacker

Apakah saya mengerti benar bahwa Anda mengompres dengan rakus? Karena itu tidak benar, pertimbangkan misalnya ABABCCCABCCC yang harus Anda pisahkan sebagai AB (ABC ^ 3) ^ 2.
Timon Knigge

Ya Anda benar tentang itu, saya harus memikirkan ini.
Optidad
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.