Числа, записані на сходинках, є цілими і знаходяться в діапазоні від до 10^6 включно. Побудуємо дерево Фенвіка на масиві довжини 10^6 + 1 (індекси масиву змінюються від до 10^6 включно), яке спочатку заповнено нулями.
Кожного разу, коли детектив проходить сходинку зі значенням , збільшуємо a_{value} на . При цьому в щоденнику він запише суму:
З урахуванням обмежень на вхідні дані, всі обчислення слід виконувати в -бітовому цілочисельному типі.
Приклад
Смоделюємо записи детектива на наведеному прикладі. Індексація масиву починається з . Числа, записані детективом, вказані під стрілками.
Сума чисел, записаних у щоденнику детектива, дорівнює
Реалізація алгоритму
Нехай максимальний розмір масиву дорівнює . Створимо дерево Фенвіка Fenwick.
#define MAX 1000001
vector<long long> Fenwick;Функція Summa0_i обчислює значення суми a_0 + a_1 + ... + a_i.
long long Summma0_i(int i)
{
long long result = 0;
for (; i >= 0; i = (i & (i + 1)) - 1)
result += Fenwick[i];
return result;
}Функція IncElement збільшує значення елемента: a_i = a_i + delta.
void IncElement(int i, int delta)
{
for (; i < MAX; i = (i | (i+1)))
Fenwick[i] += delta;
}Основна частина програми. Читаємо вхідні дані.
scanf("%d",&tests);
while (tests--)
{
scanf("%d",&n);Заповнюємо масив Fenwick нулями.
Fenwick.assign(MAX,0);Шукану суму, записану в щоденнику детектива, підраховуватимемо в змінній .
sum = 0;Послідовно обробляємо числа, записані на сходинках.
for (i = 0; i < n; i++)
{Для кожного значення , записаного на сходинці, збільшуємо a_{value} на , а також обчислюємо суму всіх раніше зустрінутих чисел, менших за . Ця сума дорівнює a_0 + a_1 + a_2 + ... + a_{value - 1}.
scanf("%d",&value);
IncElement(value, value);
sum += Summma0_i(value - 1);
}Виводимо суму всіх чисел, записаних у щоденнику детектива.
printf("%lld\n",sum);
}