Я не уверен, что должен делать ваш код, но реализовать сумму префикса на самом деле довольно легко.Например, при этом вычисляется сумма (исключительного) префикса диапазона итератора с использованием произвольной операции:
template <typename It, typename F, typename T>
inline void prescan(It front, It back, F op, T const& id) {
if (front == back) return;
typename iterator_traits<It>::value_type accu = *front;
*front++ = id;
for (; front != back; ++front) {
swap(*front, accu);
accu = op(accu, *front);
}
}
Это соответствует стилю интерфейса алгоритмов стандартной библиотеки C ++.
Чтобы использовать егоиз своего кода вы могли бы написать следующее:
prescan(x, x + n, std::plus<int>());
Вы пытаетесь реализовать параллельную сумму префикса?Это имеет смысл, только когда вы на самом деле распараллеливаете свой код.В настоящее время ваш код выполняется последовательно и не получает ничего от более сложной логики «разделяй и властвуй», которую вы, похоже, используете.
Кроме того, в вашем коде действительно есть ошибки.Самый важный из них:
for(int i=0;i<=(Log(n)-1);i++)
Здесь вы выполняете итерацию до floor(log(n)) - 1
.Но в псевдокоде говорится, что вам нужно выполнять итерацию до ceil(log(n)) - 1
.
. Кроме того, учтите следующее:
for (int j=0;j<=n-1;j++)
Это не очень обычно.Обычно вы пишете такой код следующим образом:
for (int j = 0; j < n; ++j)
Обратите внимание, что я использовал <
вместо <=
и изменил границы от j - 1
до j
.То же самое относится и к внешнему циклу, поэтому вы получите:
for (int i = 0; i < std::log(n); ++i)
Наконец, вместо std::powf
, вы можете использовать тот факт, что pow(2, x)
совпадает с 1 << x
(т.е.используя тот факт, что операционная база 2 эффективно реализована как битовые операции).Это означает, что вы можете просто написать:
if (j >= 1 << i)
x[j] += x[j - (1 << i)];