Once detective Saikat was solving a murder
case. While going to the crime scene he took the stairs and saw that a number
is written on every stair. He found it suspicious and decides to remember all
the numbers that he has seen till now. While remembering the numbers he found
that he can find some pattern in those numbers. So he decides that for each
number on the stairs he will note down the sum of all the numbers previously
seen on the stairs which are smaller than the present number. Calculate the sum
of all the numbers written on his notes diary.
Input. First line gives the number of test cases t (t
≤ 10). 2t lines follow. First
line gives the number of stairs n (1 ≤ n ≤ 105).
Next line gives n numbers written on
the stairs. All numbers will be between 0 and 106.
Output. For each test case print the final sum in a separate
line.
Sample
input
1
5
1 5 3 6 4
Sample output
15
data structures – Fenwick tree
Числа, записанные на ступеньках, являются
целыми и ограничены 0 снизу и 106 сверху. Построим дерево Фенвика по
массиву a длины 106 + 1 (индексы массива изменяются от 0 до
106 включительно), изначально элементы которого равны нулю. Каждый
раз, когда детектив будет проходить ступеньку со значением value, будем
увеличивать avalue на value. При этом в дневнике он
будет записывать сумму a0 + a1 + a2
+ … + avalue-1.
Учитывая ограничения на входные данные,
вычисления следует производить в 64-битовом целочисленном типе.
Пример
Промоделируем записи детектива на приведенном
примере. Индексация массива начинается с 0. Числа, записываемые детективом,
приведены под стрелками.
Сумма чисел, записанных в дневнике
детектива, равна 0 + 1 + 1 + 9 + 4 = 15.
Объявим размер MAX массива а и дерево Фенвика Fenwick.
#define MAX 1000001
vector<long long> Fenwick;
Вычисление суммы a0 + a1
+ ... + ai.
long long Summma0_i(int i)
{
long long
result = 0;
for (; i >= 0; i = (i & (i + 1))
- 1)
result += Fenwick[i];
return result;
}
Увеличение элемента: ai = ai
+ delta.
void IncElement(int i, int delta)
{
for (; i < MAX; i = (i | (i+1)))
Fenwick[i] += delta;
}
Основная часть
программы. Читаем входные данные. Заполняем массив Fenwick нулями.
scanf("%d",&tests);
while(tests--)
{
scanf("%d",&n);
Fenwick.assign(MAX,0);
for(sum = i = 0; i < n; i++)
{
Для каждого
значения value, записанного на ступеньке, увеличиваем avalue на value, а
также подсчитываем сумму чисел, записанных ранее на ступеньках и меньших value.
Эта сумма равна a0 + a1 + a2 + … + avalue-1.
scanf("%d",&value);
IncElement(value, value);
sum += Summma0_i(value-1);
}
Выводим сумму всех чисел, записанных в
дневнике детектива.
printf("%lld\n",sum);
}