[Dr.Lib]Note:Algorithms – Binary Indexed Tree 树状数组

Via http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees

Introduction

We often need some sort of data structure to make our algorithms faster. In this article we will discuss the Binary Indexed Trees structure. According to Peter M. Fenwick, this structure was first used for data compression. Now it is often used for storing frequencies and manipulating cumulative frequency tables.

Let's define the following problem: We have n boxes. Possible queries are
1. add marble to box i
2. sum marbles from box k to box l

The naive solution has time complexity of O(1) for query 1 and O(n) for query 2. Suppose we make m queries. The worst case (when all queries are 2) has time complexity O(n * m). Using some data structure (i.e. RMQ) we can solve this problem with the worst case time complexity of O(m log n). Another approach is to use Binary Indexed Tree data structure, also with the worst time complexity O(m log n) — but Binary Indexed Trees are much easier to code, and require less memory space, than RMQ.

 

Notation


  BIT – Binary Indexed Tree
  MaxVal – maximum value which will have non-zero frequency
  f[i] – frequency of value with index i, i = 1 .. MaxVal
  c[i] – cumulative frequency for index i (f[1] + f[2] + … + f[i])
  tree[i] – sum of frequencies stored in BIT with index i (latter will be described what index means); sometimes we will write tree frequency instead sum of frequencies stored in BIT
  num¯ – complement of integer num (integer where each binary digit is inverted: 0 -> 1; 1 -> 0 )
NOTE: Often we put f[0] = 0, c[0] = 0, tree[0] = 0, so sometimes I will just ignore index 0.
 

Basic idea


Each integer can be represented as sum of powers of two. In the same way, cumulative frequency can be represented as sum of sets of subfrequencies. In our case, each set contains some successive number of non-overlapping frequencies.

idx is some index of BIT. r is a position in idx of the last digit 1 (from left to right) in binary notation. tree[idx] is sum of frequencies from index (idx – 2^r + 1) to index idx (look at the Table 1.1 for clarification). We also write that idx is responsible for indexes from (idx – 2^r + 1) to idx (note that responsibility is the key in our algorithm and is the way of manipulating the tree).

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
f 1 0 2 1 1 3 0 4 2 5 2 2 3 1 0 2
c 1 1 3 4 5 8 8 12 14 19 21 23 26 27 27 29
tree 1 1 2 4 1 4 0 12 2 7 2 11 3 4 0 29

Table 1.1

 

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
tree 1 1..2 3 1..4 5 5..6 7 1..8 9 9..10 11 9..12 13 13..14 15 1..16

Table 1.2 – table of responsibility


Image 1.3 – tree of responsibility for indexes (bar shows range of frequencies accumulated in top element)

Image 1.4 – tree with tree frequencies

 

Suppose we are looking for cumulative frequency of index 13 (for the first 13 elements). In binary notation, 13 is equal to 1101. Accordingly, we will calculate c[1101] = tree[1101] + tree[1100] + tree[1000] (more about this later).

Isolating the last digit
NOTE: Instead of "the last non-zero digit," it will write only "the last digit."

There are times when we need to get just the last digit from a binary number, so we need an efficient way to do that. Let num be the integer whose last digit we want to isolate. In binary notation num can be represented as a1b, where a represents binary digits before the last digit and b represents zeroes after the last digit.

Integer -num is equal to (a1b)¯ + 1 = a¯0b¯ + 1. b consists of all zeroes, so consists of all ones. Finally we have

-num = (a1b)¯ + 1 = a¯0b¯ + 1 = a¯0(0…0)¯ + 1 = a¯0(1…1) + 1 = a¯1(0…0) = a¯1b.

Now, we can easily isolate the last digit, using bitwise operator AND (in C++, Java it is &) with num and -num:

           a1b
&      a¯1b
——————–
= (0…0)1(0…0)

 

继续阅读

OI旧约

一二十一月十一 福州那个学校里
闽江那河畔边流淌的旋律
在师大附中的机房里
没有人会去在意 那敲键盘的声音
爆搜模拟输样例 平衡树的红黑心
OI为了生计写着对拍机
古代战争的密码是提高的前奏曲

你写着递归 优雅美丽
数据却逃避
我会像丽洁记录我们约定的第一
快排高精写不出的AC
像国王右手隐没题海里
我为你对拍了几百数据
也是注定没结局
键盘在屏幕雕刻着唯一
叹息OJ永远不懂我的心
我的卡时动规 也没挽回你
继续阅读

OIer&ACMER的十最

最有成就感的时刻:AC了一道POJAC率低于10%的题目 

题目错了却最踏实的时刻:PE 

最棘手的时刻:TLE 

最粗心的时刻:CE 

最无奈的时候:递归RE 

最郁闷的时候:无数次修改后submit依然WA

最无语的时刻:调试数据也被输出结果OLE

最贪婪的时刻:空间换取时间…TLE

最夸张的时刻:惊现SE

最被BS的时刻:提交恶意代码…服务器死掉….

最幸福的时刻:AK

[译漫画]深度优先

Via http://www.guokr.com/post/401071/  ENT

                                                                                                                                  
“事实上,广先在一般意义上对约会都更加有效——它指出,先和许多人随意地约会再考虑深入发展关系,要比在每个人身上都依次花五年要更加恰当。”nip4k7