CF 102697094 - Computer Love
We are given an inclusive integer interval from x to y. Among all numbers in that interval, we need to find the largest one that is a power of two. If the interval contains no power of two, we print -1. The answer must fit in a signed 32-bit integer.
Rating: -
Tags: -
Solve time: 51s
Verified: yes
Solution
Problem Understanding
We are given an inclusive integer interval from x to y. Among all numbers in that interval, we need to find the largest one that is a power of two. If the interval contains no power of two, we print -1. The answer must fit in a signed 32-bit integer.
The relevant powers of two are 1, 2, 4, 8, 16, .... Since the answer fits in a signed 32-bit integer, the largest possible answer is 2^30 = 1073741824. The next power, 2^31, is outside the signed 32-bit range. This gives us only 31 candidate powers to consider.
The time limit is 1 second and the memory limit is 256 MB. The statement does not impose a large array or graph structure because the input consists of only two integers. A linear scan over every integer in the interval could still require more than two billion iterations when the interval is large, so the useful observation is that powers of two are extremely sparse. Checking only the powers themselves takes logarithmic time.
There are several boundary cases that can make a careless implementation fail. If the interval itself contains a power of two, the endpoints are inclusive. For example, with input 8 8, the correct output is 8. An implementation that searches only strictly between the endpoints would incorrectly print -1.
Another case is when the upper endpoint is not a power of two but the largest power below it is inside the interval. For input 86 375, the powers near the interval are 64, 128, and 256, so the answer is 256. Choosing the first power that is at least x would be wrong because 128 is valid but not maximal.
Finally, an interval can contain no power of two at all. For input 35 55, the surrounding powers are 32 and 64, both outside the interval, so the answer is -1. A careless implementation that simply computes the largest power not exceeding y would get 32 and forget to verify that it is also at least x.
Approaches
The direct approach is to inspect every integer from x through y, test whether it is a power of two, and remember the largest successful value. The method is correct because every possible answer is explicitly examined. A positive integer is a power of two exactly when its binary representation contains one set bit, so the test can be done with a bit operation such as v & (v - 1) == 0.
The problem is the number of integers examined. In the worst case, an interval such as [1, 2147483647] contains 2147483647 candidates. Even if each candidate takes only a few constant-time operations, billions of iterations are far beyond a 1 second limit.
The brute-force works because it checks every possible answer, but fails when the interval is wide. The observation that unlocks the faster solution is that we do not need to inspect the ordinary integers at all. The only possible answers are powers of two, and consecutive powers differ by multiplication by two. Starting from 1, we can generate every relevant candidate with repeated doubling.
There are only about 31 powers of two in the signed 32-bit range. We can either generate them all and keep the largest one in the interval, or find the largest power of two not exceeding y and check whether it is at least x. The second formulation is especially simple. Once we reach the largest power p satisfying p <= y, every larger power is automatically greater than y, so p is the only candidate that could possibly be the answer.
| Approach | Time Complexity | Space Complexity | Verdict |
|---|---|---|---|
| Brute Force | O(y - x + 1) | O(1) | Too slow |
| Optimal | O(log y) | O(1) | Accepted |
Algorithm Walkthrough
- Read
xandy. The interval is inclusive, so both endpoints are allowed to be the answer. - Start with
p = 1, the smallest positive power of two. Every subsequent power can be obtained by doubling the previous one. - While doubling
pwould still keep it at mosty, replacepwith2 * p. When the loop stops,pis the largest power of two satisfyingp <= y. - Check whether
p >= x. If it is, thenplies inside[x, y], and it is the largest possible power of two in that interval, so printp. - If
p < x, print-1. Sincepis already the largest power of two that does not exceedy, every other power of two is either at mostpor greater thany. Thus no power can lie inside the interval.
The invariant is that after every iteration, p is a power of two and is the largest generated power not exceeding its current upper bound. At termination, p is the largest power of two at most y. If it is also at least x, it is exactly the largest valid answer. If it is below x, there cannot be any valid power because all later powers exceed y.
Python Solution
import sys
input = sys.stdin.readline
def solve():
x, y = map(int, input().split())
p = 1
while p * 2 <= y:
p *= 2
if x <= p <= y:
print(p)
else:
print(-1)
if __name__ == "__main__":
solve()
The first line of solve reads the two endpoints. No array or auxiliary data structure is needed because the answer depends only on the current power of two.
The variable p starts at 1. The loop doubles it while the next power still fits below or exactly at y. Using p * 2 <= y rather than doubling first avoids creating an unnecessary candidate above the upper bound.
After the loop, p is guaranteed to satisfy p <= y when y >= 1. The final condition checks the other side of the interval, p >= x. Writing the full condition as x <= p <= y also makes the inclusive boundaries explicit.
Python integers do not overflow, so even the temporary value after the final possible doubling would be safe. In a language with fixed-width integers, the implementation should avoid shifting into a signed overflow range. Here the answer itself is guaranteed to fit in a signed 32-bit integer.
If y < 1, the loop performs no doubling and p remains 1. The final p <= y check fails, so the algorithm correctly reports -1. This also handles intervals containing only non-positive integers.
Worked Examples
For the first sample, the input is 6 18.
| Step | p before |
2 * p <= y |
p after |
|---|---|---|---|
| Start | 1 | 2 <= 18 |
1 |
| 1 | 1 | true | 2 |
| 2 | 2 | true | 4 |
| 3 | 4 | true | 8 |
| 4 | 8 | true | 16 |
| 5 | 16 | 32 <= 18 false |
16 |
The final value is 16. It satisfies 6 <= 16 <= 18, so the output is 16. The trace shows why we only need the largest power below the upper endpoint. Every larger power starts at 32, already outside the interval.
For the second sample, the input is 35 55.
| Step | p before |
2 * p <= y |
p after |
|---|---|---|---|
| Start | 1 | 2 <= 55 |
1 |
| 1 | 1 | true | 2 |
| 2 | 2 | true | 4 |
| 3 | 4 | true | 8 |
| 4 | 8 | true | 16 |
| 5 | 16 | true | 32 |
| 6 | 32 | 64 <= 55 false |
32 |
The final value is 32, but it is smaller than x = 35. The next power is 64, which exceeds y = 55, so there is no valid power of two and the algorithm prints -1. This trace demonstrates why the final lower-bound check is necessary.
For the third sample, 86 375, the generated powers eventually reach 256. Doubling again gives 512, which is above 375, so 256 is the largest power not exceeding the upper endpoint. Since 256 >= 86, it is the answer.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(log y) | Each iteration doubles the current power of two. |
| Space | O(1) | Only the two input values and one power value are stored. |
For 32-bit signed values, the loop executes at most about 31 times. This is effectively constant work for the actual problem constraints and is comfortably within the 1 second time limit and 256 MB memory limit.
Test Cases
import sys
import io
def solve():
input = sys.stdin.readline
x, y = map(int, input().split())
p = 1
while p * 2 <= y:
p *= 2
if x <= p <= y:
print(p)
else:
print(-1)
def run(inp: str) -> str:
old_stdin = sys.stdin
old_stdout = sys.stdout
sys.stdin = io.StringIO(inp)
sys.stdout = io.StringIO()
solve()
result = sys.stdout.getvalue()
sys.stdin = old_stdin
sys.stdout = old_stdout
return result
# Provided samples
assert run("6 18\n") == "16\n", "sample 1"
assert run("35 55\n") == "-1\n", "sample 2"
assert run("86 375\n") == "256\n", "sample 3"
# Minimum-size and exact power
assert run("1 1\n") == "1\n", "minimum interval containing the smallest power"
# Both endpoints are powers of two
assert run("8 16\n") == "16\n", "upper endpoint must be considered"
# No power in the interval
assert run("5 7\n") == "-1\n", "interval between consecutive powers"
# Large boundary case
assert run("1 2147483647\n") == "1073741824\n", "largest signed-32-bit range"
# Single non-power value
assert run("2147483647 2147483647\n") == "-1\n", "maximum value is not a power of two"
# Lower boundary just above a power
assert run("9 16\n") == "16\n", "lower boundary above previous power"
| Test input | Expected output | What it validates |
|---|---|---|
1 1 |
1 |
Smallest possible positive power and inclusive endpoints |
8 16 |
16 |
Both endpoints can be powers and the upper one must win |
5 7 |
-1 |
No power exists between consecutive powers |
1 2147483647 |
1073741824 |
Largest relevant signed 32-bit boundary |
2147483647 2147483647 |
-1 |
Maximum integer itself is not a power of two |
9 16 |
16 |
Lower bound excludes the previous power |
Edge Cases
When the interval contains exactly one power, the algorithm handles it through the inclusive comparison. For the input 8 8, p eventually becomes 8, and the condition 8 <= 8 <= 8 succeeds, so the output is 8. An implementation using strict inequalities would fail here.
When there is no power of two in the interval, the largest power not exceeding y falls below x. For 35 55, the loop stops at 32. Since 32 < 35, the algorithm prints -1. The next power, 64, cannot be considered because it is already larger than y.
When the interval is extremely large, the algorithm does not depend on its width. For 1 2147483647, it generates powers only up to 1073741824. The next power is 2147483648, which exceeds the upper endpoint, so the answer is 1073741824. A scan through every integer would require more than two billion iterations, while this solution needs only a few dozen.
When the endpoints are both the same non-power value, such as 2147483647 2147483647, the algorithm still works without a special case. The largest power not exceeding that value is 1073741824, which is below the lower endpoint because both endpoints equal 2147483647. The final check consequently produces -1.
The central idea is simple enough to reuse: when the desired values form a sparse sequence with a predictable next element, search that sequence rather than scanning every value in the numeric interval. Here the sequence is 1, 2, 4, 8, ..., so repeated doubling reduces a potentially billions-of-iterations search to logarithmic time.