Fenwick Tree

June 27, 2016
Algorithm

Fenwick Tree的原理是,把一个前缀和划分成多个子序列的和,子序列的个数是当前前缀和元素个数的数字二进制表示中的1的个数。

Perl实现:

#!/usr/bin/env perl -n
#===============================================================================
#         FILE: fenwick_tree.pl
#       AUTHOR: Sabastian (liuxueyang.github.io), liuxueyang457@gmail.com
# ORGANIZATION: Hunan University
#      CREATED: 2016/06/26 23时27分06秒
#===============================================================================

use strict;
use warnings;
use utf8;
use 5.014;

chomp;
my @fenwick;
my @array = split;
unshift @array, 0;
unshift @fenwick, 0;

sub lowbit { $_[0] & -$_[0]; }

sub build_fenwick_tree {
    for (1..$#array) {
        for my $j ($_-lowbit($_)+1..$_) {
            $fenwick[$_] += $array[$j]
        }
    }
}

sub modify_fenwick_tree {
    # two arguments
    # 1.index: the index of the array to modify
    # 2.delta: substract result of new value to the old value of the element
    my ($index, $delta) = @_;
    while ($index <= @fenwick) {
        $fenwick[$index] += $delta;
        $index += lowbit($index);
    }
}

sub sum_fenwick_tree {
    # 1 argument: index
    my ($ans, $i) = (0, $_[0]);
    while ($i > 0) {
        $ans += $fenwick[$i];
        $i -= lowbit($i);
    }
    $ans;
}


build_fenwick_tree();
print join(" ", @fenwick[1..$#fenwick]), "\n";

modify_fenwick_tree(3, 3);
print join(" ", @fenwick[1..$#fenwick]), "\n";

print sum_fenwick_tree(3), "\n";

# input
# 1 2 3 4 5
# output
# 1 3 3 10 5
# 1 3 6 13 5
# 9
#

comments powered by Disqus