| title | Sparse Table | ||
|---|---|---|---|
| tags |
|
Sparse table aralıklardaki elemanların toplamı, minimumu, maksimumu ve EBOB'ları gibi sorgulara
Bu veri yapısı durumu değişmeyen, sabit bir veri üzerinde ön işlemler yaparak kurulur. Dinamik veriler için kullanışlı değildir. Veri üzerinde herhangi bir değişiklik durumda Sparse table tekrardan kurulmalıdır. Bu da maliyetli bir durumdur.
Sparse table iki bouyutlu bir dizi şeklinde,
// Toplam sorgusu icin kurulmus Sparse Table Yapisi
const int n;
const int LOG = log2(n);
int a[n + 1], ST[2 * n][LOG + 1];
void build() {
for (int i = 1; i <= n; i++) {
// [i,i] araliginin cevabi dizinin i indeksli elemanina esittir.
ST[i][0] = a[i];
}
for (int i = 1; i <= LOG; i++)
for (int j = 1; j <= n; j++) {
// [i,i+2^(j)-1] araliginin cevabi
// [i,i+2^(j - 1) - 1] araligi ile [i+2^(j - 1),i+2^j-1] araliginin
// cevaplarinin birlesmesiyle elde edilir
ST[i][j] = ST[i][j - 1] + ST[i + (1 << (j - 1))][j - 1];
}
return;
}Herhangi bir
-
$[l,r]$ aralığını cevaplarını önceden hesapladığımız aralıklara parçala.- Sadece
$2$ 'nin kuvveti uzunluğunda parçaların cevaplarını sakladığımız için aralığımızı$2$ 'nin kuvveti uzunluğunda aralıklara ayırmalıyız.$[l,r]$ aralığının uzunluğunun ikilik tabanda yazdığımızda hangi aralıklara parçalamamız gerektiğini bulmuş oluruz.
- Sadece
- Bu aralıklardan gelen cevapları birleştirerek
$[l,r]$ aralığının cevabını hesapla.
Herhangi bir aralığın uzunluğunun ikilik tabandaki yazılışındaki
Örneğin:
// toplam sorgusu
int query(int l, int r) {
int res = 0;
for (int i = LOG; i >= 0; i--) {
// her seferinde uzunlugu r - l + 1 gecmeyecek
// en buyuk araligin cevabi ekleyip l'i o araligin sonuna cekiyoruz.
if (l + (1 << i) <= r) {
res += ST[l][i];
l += (1 << i);
}
}
return res;
}Sparse Table veri yapısının diğer veri yapılarından farklı olarak
Herhangi bir aralığın cevabını hesaplarken bu aralıktaki herhangi bir elemanı birden fazla kez değerlendirmemiz cevabı etkilemez. Bu durum aralığımızı
int RMQ(int l, int r) {
// log[] dizisinde her sayinin onceden hesapadigimiz log2 degerleri saklidir.
int j = log[r - l + 1];
return min(ST[l][j], ST[r - (1 << j) + 1][j]);
}Sparse Table veri yapısı ile ilgili örnek bir probleme buradan{target="_blank"} ulaşabilirsiniz.