Diberikan dua string , kami menulis untuk penggabungan mereka. Mengingat string dan integer , kita menulis untuk gabungan dari salinan . Sekarang diberi string, kita dapat menggunakan notasi ini untuk 'kompres' itu, yaitu dapat ditulis sebagai . Mari kita sebut berat darikompresijumlah karakter yang muncul di dalamnya, sehingga berat adalah dua, dan berat (akompresidari ) adalah tiga ( terpisah dihitung secara terpisah).
Sekarang pertimbangkan masalah komputasi kompresi 'teringan' dari string dengan . Setelah beberapa pemikiran ada pendekatan pemrograman dinamis yang berjalan di atau tergantung pada pendekatan yang tepat.
Namun, saya telah diberitahu bahwa masalah ini dapat diselesaikan dalam waktu , 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 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 :-)
sumber
Jawaban:
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.(pℓi,rℓi) ℓ=1,2,… p1i≥1 r≥2 S[i−rp1i+1,i−p1i]=S[i−(r−1)p1i+1,i]. p1i r1i r pi Li=0 (pℓi,rℓi)
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 .p2i (r1i−1)p1i S[i−r2ip2i+1,i−p2i]=S[i−(r2i−1)p2i+1,i] r2i≥2 r2i p2i pℓi (rℓ−1i−1)pℓ−1i pℓi Li=ℓ−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)) pℓi ℓ pℓ+1i (rℓi−1)pℓi pℓi/2
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←) S ∑iLi T(S←) pji nca(v(i),v(i−pji)) v(i−pji) 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) (pji,rji) O(n+∑iLi)
Beri tahu saya jika ini masuk akal.
sumber
Ada string S panjang awal Anda n. Berikut adalah pseudo-code dari metode ini.
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.
Ini adalah global O (n²log (n)).
sumber