后继图是一个有向图,其中每个顶点的度数都大于一,即,一个边恰好在每个节点处开始。后继图由一个或多个组件组成,每个组件都包含一个循环以及通往该循环的一些路径。
后继图有时也称为功能图。这样做的原因是,任何后继图形都对应于定义图形边缘的函数。函数的参数是图形的节点,函数提供该节点的后继对象。例如函数
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
succ(x) | 3 | 5 | 7 | 6 | 2 | 2 | 1 | 6 | 3 |
上面的函数定义了下图:
由于后继图的每个节点都具有唯一的后继,因此还可以定义函数succ(x,k) ,该函数在遍历从节点x开始并向前走k时向该节点提供。例如,在上面的图succ(4,6)= 2中,因为可以通过从节点4步行6个步骤来到达节点2 :
计算succ( x,k )值的一种直接方法是从节点x开始并向前走k个步骤,这需要O(k)时间。但是,使用预处理,可以仅在O(logk)时间中计算succ( x,k )的任何值。
这个想法是预先计算succ( x,k )的所有值,其中k是2的幂,并且最多是u ,其中u是我们将要行走的最大步数。由于我们可以使用以下递归,因此可以高效地完成此操作:
预先计算值需要O(n * log u)时间,因为为每个节点都计算了O(log u)值。在上图中,第一个值如下:
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
succ(x, 1) | 3 | 5 | 7 | 6 | 2 | 2 | 1 | 6 | 3 |
succ(x, 2) | 7 | 2 | 1 | 2 | 5 | 5 | 3 | 2 | 7 |
succ(x, 4) | 3 | 2 | 7 | 2 | 5 | 5 | 1 | 2 | 3 |
succ(x, 8) | 7 | 2 | 1 | 2 | 5 | 5 | 3 | 2 | 7 |
… |
此后,可以通过将步数k表示为2的幂的和来计算succ( x,k )的任何值。
例如,如果要计算succ(x,11)的值,我们首先形成表示形式11 = 8 + 2 + 1。
例如,在上图中
这样的表示总是由O(log k)个部分组成,因此计算succ( x,k )的值需要O(log k)的时间。