Bit complexity 2026-10-31
The number of elementary operations on bits required by an algorithm. Arithmetic-operation counts treat operations on entire integers as units, whereas bit complexity charges for the sizes of their operands. An algorithm using few multiplications can therefore require substantially more bit operations when the operands grow. State the model when comparing bounds for repeated squaring or dynamic programming counts.
Integer logarithm 2026-10-31
For integers and , the integer logarithm is the largest nonnegative integer such that . Equivalently,The equivalence follows from the monotonicity of exponentiation in its exponent and the definition of the floor function. For example, , so the base-three integer logarithm of is .
A multiplication loop maintains and accepts another factor while . Repeated squaring makes the search faster: precompute starting at , and consider these factors in decreasing . Include a factor when the accumulated product remains at most . If , the loop invariant before considering is . Accepting exactly when halves that uncertainty, proving the greedy algorithm returns . This takes arithmetic operations; it is not the same claim as this bound on bit complexity.
For positive operands in bounded integer arithmetic, test before multiplying by . Integer division makes this equivalent to while preventing integer overflow in a rejected candidate.
Set . Independently sample an edge coloring exactly as in part (d), count its monochromatic copies of by examining all four-vertex subsets, and accept precisely when . Otherwise start over with a fresh edge coloring.
To prove an expected polynomial time bound, the existence argument alone is insufficient: we need a lower bound on the acceptance probability at this exact threshold. Since is a nonnegative integer with expectation , rejection implies . Markov's inequality therefore gives the integer-valued expectation threshold restart boundThe number of attempts has a geometric distribution, with expectation at most . Sampling the edge coloring costs random bits, and checking all four-vertex subsets costs operations, since only six edges must be tested per subset. HenceThis is a randomized algorithm that always returns an edge coloring meeting the original threshold and terminates with probability one. The stated operation count uses -bit counters; counting their bit complexity explicitly introduces at most a further logarithm factor and still gives polynomial time. For , return any edge coloring immediately.
Order the edges arbitrarily and fix their colours one at a time. After a partial assignment , regard all unassigned edges as independent fair red/blue choices, and computeThe conditional expectation of a monochromatic clique count is easy to compute. For each four-vertex subset , let be the number of its six edges still unassigned. Its contribution to isIn the second case, every remaining edge must match the already fixed colour; this includes a completely fixed monochromatic copy, for which and the contribution is one. In the last case, the six unassigned edges may become either all red or all blue. By linearity of expectation,For the next unassigned edge , compute and . The law of total expectation givesChoose the colour with the smaller value, resolving a tie by a fixed rule. At least one is at most their average, so the loop invariant is that never increases. Initially ; once every edge is fixed, there is no randomness left and . Therefore the method of conditional expectations guaranteesA direct implementation recomputes both sums over all four-vertex subsets for each of the edges, requiring arithmetic operations. The comparisons can be exact: every contribution is a multiple of , so store as an integer with bits. This gives bit complexity with elementary arithmetic, and hence a deterministic polynomial time construction. No random sampling is performed by this derandomization.
In binary long division, first double the divisor until it exceeds
x, then halve it successively. Keep p = 2^j and d = y*p, so no exponentiation is needed inside a loop:q := 0; r := x;
j := 0; p := 1; d := y;
WHILE d <= x DO
d := 2*d;
p := 2*p;
j := j+1
END;
WHILE j > 0 DO
d := d DIV 2;
p := p DIV 2;
j := j-1;
IF r >= d THEN
r := r-d;
q := q+p
END
ENDThe first loop invariant is , , , and . Every doubling preserves it. For integer inputs, after at most iterations when ,
d > x; if , this loop has no iterations. The unbounded increase of proves termination. Equivalently, one can use the decreasing nonnegative loop variant while the guard is true.At the top of the second loop the loop invariant isIt holds on entry because
d > x = r. Suppose the old d is and the old p is . After the three halving assignments, and the old remainder satisfies . If , the desired new bound already holds. Otherwise subtracting leaves and adding to q preserves because . The divisions by two are exact: before each halving, j > 0 makes both p and d even.The loop variant
j decreases by one each iteration. At exit , so d = y and the loop invariant gives the required remainder bound. The work per iteration is constant in the unit-cost model, and the two loops have the same number of iterations. For ,The case , including , takes constant time. These are arithmetic-operation counts with sufficient range for the doubled values; arbitrary-precision arithmetic incurs additional bit complexity. If the inputs were arbitrary positive real numbers, the uniform bound would depend on rather than only ; the stated is the conventional integer division interpretation.Store a second array For the second loop, write . Immediately before processing , its loop invariant isInitially the failed squaring guard gives ; this also holds when , since then . The test succeeds exactly when . If successful, adding selects that binary digit; otherwise the upper bound tightens to . Either way the invariant holds for the next smaller . At , , so
weight with weight[k] = 2^k. Descending through the binary digits of the answer gives this greedy algorithm:PROCEDURE FastLog(b, n: INTEGER): INTEGER;
VAR b2, weight: ARRAY enough OF INTEGER;
top, k, i, p: INTEGER;
BEGIN
b2[0] := b; weight[0] := 1; top := 0;
WHILE b2[top]*b2[top] <= n DO
b2[top+1] := b2[top]*b2[top];
weight[top+1] := weight[top]+weight[top];
top := top+1
END;
i := 0; p := 1; k := top;
WHILE k >= 0 DO
IF p*b2[k] <= n THEN
p := p*b2[k]; i := i+weight[k]
END;
k := k-1
END;
RETURN i
END FastLog;i = L.There are squarings and descending tests. For fixed , this is arithmetic operations, hence logarithmic in the bit length of , and also within the weaker bound. This counts arithmetic operations on integers as unit cost; bit complexity would also charge for the growing operands. No division is used.
Use dynamic programming in increasing order of the maximum permitted part and then of the remaining sum. Let Require . The outer loop invariant says all rows below equal . The inner loop invariant additionally says entries before column in the current row are correct. Its dependencies are the previous row and the earlier column , so no future entry is read. Each state is evaluated once, giving arithmetic operations and stored counts. A memoization table around part (a)'s recursion is another valid way to share states; its entries need a separate “computed” flag because zero is a legitimate answer. Growing count sizes affect bit complexity and can cause integer overflow in a fixed-width
Count be a sufficiently wide integer type and let table have dimensions (MaxN+1) by (MaxN+1):PROCEDURE CountPartitions(n: INTEGER): Count;
VAR i, j: INTEGER;
table: ARRAY MaxN+1, MaxN+1 OF Count;
BEGIN
table[0,0] := 1; j := 1;
WHILE j <= n DO table[0,j] := 0; j := j+1 END;
i := 1;
WHILE i <= n DO
table[i,0] := 1; j := 1;
WHILE j <= n DO
table[i,j] := table[i-1,j];
IF j >= i THEN
table[i,j] := table[i,j] + table[i,j-i]
END;
j := j+1
END;
i := i+1
END;
RETURN table[n,n]
END CountPartitions;Count. Unit-cost model 2026-10-31
A computation-cost convention assigning constant cost to specified primitive operations. For exact unbounded integer arithmetic this can differ substantially from bit complexity: a multiplication of increasingly large values is one primitive operation but requires more bit operations. State which convention is used when estimating an algorithm's running time.