Brainstorming Quiz, Day - 5 Solution
This blog explains how to efficiently find ACES numbers (divisible by their square root) within a range using binary search for square roots and optimized checks, avoiding brute force for large inputs.
Tilak Thapa
Sat, Dec 7, 2024
2 min read
Answer: 13168380
Short Explanation:
The problem involves finding special numbers (ACES numbers) between two very large limits ll and rr. A number is considered ACES if it is divisible by the largest whole number less than or equal to its square root.
Approach:
- Efficient Square Root Calculation: A binary search is used to find the square root for very large numbers without relying on direct mathematical operations.
- Check Possible ACES Numbers:
For each valid square root kk between the lower and upper bounds:
- Numbers like k^2, k(k+1), and k(k+2) are checked to see if they are within the range [l,r][l, r].
- These numbers are also checked to ensure divisibility by k.
- Optimization: Instead of checking all numbers between ll and rr, only potential candidates derived from square roots are evaluated, making the process faster.
The program calculates and counts these numbers efficiently, even for very large inputs, and outputs the total count.
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll bs_sqrt(ll x) {
ll left = 0, right = 2000000123;
while (right > left) {
ll mid = (left + right) / 2;
if (mid * mid > x) right = mid;
else left = mid + 1;
}
return left - 1;
}
int main(){
ll l = 987642878877987659, r = 996386656794592367, ans = 0;
ll left_sqrt = bs_sqrt(l);
ll right_sqrt = bs_sqrt(r);
ans = max(ans, right_sqrt - left_sqrt - 1) * 3;
if (left_sqrt * left_sqrt >= l && left_sqrt * left_sqrt <= r) ans++;
if ((left_sqrt * (left_sqrt + 1) >= l) && (left_sqrt * (left_sqrt + 1) <= r)) ans++;
if ((left_sqrt * (left_sqrt + 2) >= l) && (left_sqrt * (left_sqrt + 2) <= r)) ans++;
if (left_sqrt != right_sqrt) {
if ((right_sqrt * right_sqrt >= l) && (right_sqrt * right_sqrt <= r)) ans++;
if ((right_sqrt * (right_sqrt + 1) >= l) && (right_sqrt * (right_sqrt + 1) <= r)) ans++;
if ((right_sqrt * (right_sqrt + 2) >= l) && (right_sqrt * (right_sqrt + 2) <= r)) ans++;
}
cout << ans << endl;
return 0;
}