Pilləkənlər üzərində yazılmış ədədlər tam ədədlərdir və -dan 10^6-ya kimi (daxil olmaqla) aralıqdadır. 10^6 + 1 uzunluğunda sıfırlarla doldurulmuş massivində Fenwick ağacını quracağıq (massivin indeksləri -dan 10^6-ya kimi dəyişir).
Hər dəfə dedektiv dəyəri olan bir pilləkəndən keçəndə, a_{value}-ı qədər artıracağıq. Həmin vaxt gündəlikdə o, məbləğini yazacaq:
Giriş verilənlərinin məhdudiyyətlərini nəzərə alaraq, bütün hesablamaları bitlik tam ədəd tipində yerinə yetirmək lazımdır.
Məsələnin nümunəsi
Verilmiş nümunəni istifadə edərək dedektivin yazılarını simulyasiya edək. Massivin indeksləşdirilməsi -dan başlayır. Dedektiv tərəfindən yazılmış ədədlər oxların altında yerləşdirilib.
Dedektivin gündəliyində yazılmış ədədlərin cəmi bərabərdir:
Alqoritmin realizasiyası
Qoy massivin maksimal ölçüsü olsun. Fenwick ağacını yaradaq.
#define MAX 1000001
vector<long long> Fenwick;Summa0_i funksiyası a_0 + a_1 + ... + a_i cəm məbləğini hesablayır.
long long Summma0_i(int i)
{
long long result = 0;
for (; i >= 0; i = (i & (i + 1)) - 1)
result += Fenwick[i];
return result;
}IncElement funksiyası elementi artırır: a_i = a_i + delta.
void IncElement(int i, int delta)
{
for (; i < MAX; i = (i | (i+1)))
Fenwick[i] += delta;
}Proqramın əsas hissəsi. Giriş verilənlərini oxuyuruq.
scanf("%d",&tests);
while (tests--)
{
scanf("%d",&n);Fenwick massivini sıfırlarla doldururuq.
Fenwick.assign(MAX,0);Dedektivin gündəliyində yazılmış olan nəticəni dəyişənində hesablayacağıq.
sum = 0;Pilləkənlər üzərində yazılmış ədədləri ardıcıl emal edirik.
for (i = 0; i < n; i++)
{Hər pilləkən üzərinə yazılmış dəyəri üçün, a_{value}-ı -a artırırıq, həmçinin -dan kiçik olan daha əvvəl görülmüş bütün ədədlərin cəmini hesablayırıq. Bu cəm a_0 + a_1 + a_2 + ... + a_{value - 1}-ə bərabərdir.
scanf("%d",&value);
IncElement(value, value);
sum += Summma0_i(value - 1);
}Dedektivin gündəliyində yazılmış bütün ədədlərin cəmini çıxarıq.
printf("%lld\n",sum);
}