When you first read about segment trees, you probably wondered "why binary tree? why not ternary?".
Let's start by analyzing segment tree's time complexity. It is O(log2n). Or is it?
We will start with a normal segtree ( segment tree ), which supports range query and point update.
To query on a range we break our segment into several subsegments [l,r] which satisfy:
k∈Nx=2kx∣ll+x=r+1
You can easily see that you need at most 2log2n subsegments for a query [l,r],r−l+1=n.
By setting l=1, let's see the decomposition as r varies:
r=1,[1,1]r=3,[1,1],[2,3]r=7,[1,1],[2,3],[4,7]r=8,[1,1],[2,3],[4,7],[8,8]
But look what happens when we set r=2⋅7=14:
r=14,[1,1],[2,3],[4,7],[8,11],[12,13],[14,14]
We used 2 times as many nodes as r=7.
Infact for all r=2⋅(2k−1),k∈N, we will need 2k subsegments!
The proof that this is the worst case is left as an exercise for the reader.
Now let's find the maximum number of subsegments for a ternary segment tree.
Again let's set l=1:
r=1,[1,1]r=2,[1,1],[2,2]r=8,[1,1],[2,2],[3,5],[6,8]r=26,[1,1],[2,2],[3,5],[6,8],[9,17],[18,26]r=16,[1,1],[2,2],[3,5],[6,8],[9,11],[12,14],[15,15],[16,16]
And again the worst cases are r=2⋅(3k−1),k∈N. But now we use 4k subsegments instead of 2k.
So for a given r a binary tree will use at most 2⌊log2r⌋, and a ternary tree 4⌊log3r⌋.
By repeating the same process for an arbitrary n-ary tree, we will see that the worst case is r=2⋅(nk−1),k∈N, and we will use 2⋅(n−1)⋅k subsegments.
We now replace k=lognN.
From that the answer seems simple: find the best n such that 2⋅(n−1)⋅lognN is minimized for arbitrary N.
We can rewrite it removing the constant as
2⋅(n−1)⋅lnNlnnlnn2⋅(n−1)
And the solution to that is: 1. We must've made a mistake.
We didn't include the updates!
Without updates of course the smaller the tree, the less nodes we have to query, and if the whole tree is 1 node, then for each query we use only 1 node.
And the cost of a point update in an n-ary tree is lognN.
If we assume the number of updates and queries is equal we get
lnn2⋅(n−1)+lnn1lnn2n−1
And the solution to that is: 2.16! Meaning that a 2.16-ary segment tree is optimal IF the number of queries is equal to the number of updates.
But let's solve it if the number of queries is Q times the number of updates:
f(n)f(n)u(n)v(n)u′(n)v′(n)f′(n)f′(n)2Q⋅lnn−[Q(2n−2)+1]⋅n12Q⋅lnn−2Q+n2Q−n12Q⋅nlnn−2Qn+2Q−1nlnn−n+1−2Q1=Q⋅lnn2n−2+lnn1=lnnQ(2n−2)+1=Q(2n−2)+1=lnn=2Q=n1=(lnn)22Q⋅lnn−[Q(2n−2)+1]⋅n1=0=0=0=0=0
This equation is impossible to solve using standard arithmetic, and the proof is again left as an exercise for the reader.
But it is absolutely possible numericaly.
For example the newton method.
To do it we need to find the derivative of nlnn−n+1−2Q1: lnn.
Now using a simple python script
Output
Run the code to see the output.
So returning to the question at the start: if there are a lot more updates than queries, than a ternary tree will be better than binary!