| title | SQRT Decomposition | |||
|---|---|---|---|---|
| tags |
|
Square Root Decomposition algoritması dizi üzerinde
Dizinin elemanları her biri yaklaşık
| Blokların Cevapları | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Dizideki Elemanlar | ||||||||||||||||
| Elemanların İndeksleri | ||||||||||||||||
*Örnek bir dizi üzerinde toplam sorgusu için kurulmuş SQRT Decompostion veri yapısı.*
void build() {
for (int i = 1; i <= n; i++) {
if (i % sq == 1) { // sq = sqrt(n)
t++; // yeni blok baslangici.
st[t] = i; // t.blok i indisli elemanda baslar.
}
fn[t] = i; // t.blokun bitisini i indisli eleman olarak guncelliyoruz.
wh[i] = t; // i indeksli eleman t.blogun icinde.
sum[t] += a[i]; // t. blokun cevabina i indeksli elemani ekliyoruz.
}
}Herhangi bir
- Cevabını aradığımız aralığın tamamen kapladığı blokların cevabını cevabımıza ekliyoruz.
- Tamamen kaplamadığı bloklardaki aralığımızın içinde olan elemanları tek tek gezerek cevabımıza ekliyoruz.
Cevabını aradığımız aralığın kapsadığı blok sayısı en fazla
| Blokların Cevapları | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Dizideki Elemanlar | ||||||||||||||||
| Elemanların İndeksleri | ||||||||||||||||
*Örnek dizideki $[3,13]$ aralığının cevabını $2.$ ve $3.$ blokların cevapları ile $3,4$ ve $11$ indeksli elemanların toplanmasıyla elde edilir.*
// [l,r] araligindaki elemanlarin toplamini hesaplayan fonksiyon.
int query(int l, int r) {
int res = 0;
if (wh[l] == wh[r]) { // l ve r ayni blogun icindeyse
for (int i = l; i <= r; i++)
res += a[i];
} else {
for (int i = wh[l] + 1; i <= wh[r] - 1; i++)
res += sum[i]; // tamamen kapladigimiz bloklarin cevaplarini ekliyoruz.
// tamamen kaplamadigimiz bloklardaki araligimiz icindeki
// elemanlarin cevaplarini ekliyoruz.
for (int i = st[wh[l]]; i <= fn[wh[l]]; i++)
if (i >= l && i <= r)
res += a[i];
for (int i = st[wh[r]]; i <= fn[wh[r]]; i++)
if (i >= l && i <= r)
res += a[i];
}
return res;
}Herhangi bir elemanın değerini güncellerken o elemanı içeren blokun değerini güncellememiz yeterli olacaktır. Dolayısıyla güncelleme işlemimimiz
void update(int x, int val) {
// x indeksli elemanin yeni degerini val degerine esitliyoruz.
sum[wh[x]] -= a[x];
a[x] = val;
sum[wh[x]] += a[x];
}SQRT Decomposition veri yapısı ile ilgili örnek bir probleme buradan{target="_blank"} ulaşabilirsiniz.