2^x * 3^y şəklində olan və 10^{18}-dən çox olmayan rəqəmlər o qədər də çox deyil. Onları yaradaraq massivində saxlayacağıq.
Müəyyən bir intervalda olan f(a, b) şəklində olan rəqəmlərin sayını aşağıdakı formada tapa bilərik:
Burada f(0, q) -dən böyük olmayan 2^x * 3^y şəklində olan rəqəmlərin sayını ifadə edir. Bu sorğunun cavabını massivində ikili axtarış yolu ilə tapa bilərik.
Nümunə
-dən çox olmayan 2^x * 3^y şəklində olan bütün rəqəmləri yaradacağıq.
intervalına rəqəm aiddir (mavi rənglə qeyd olunub).
intervalına rəqəm aiddir (yaşıl rənglə qeyd olunub).
intervalı üçün həllini tapaq:
Doğrudan da, intervalına axtarılan rəqəm aiddir:
Alqoritmin reallaşdırılması
MAX = 10^{18} sabitini və iş massivini elan edəcəyik.
#define MAX 1000000000000000000LL
vector<long long> v;preprocess funksiyası 10^{18}-dən çox olmayan bütün 2^x * 3^y şəklində olan rəqəmləri yaradır və onları massivində saxlayır. Hər bir x = 1, 2, 4, 8, ... üçün y = 1, 3, 9, 27, ... rəqəmlərini nəzərdən keçiririk, ta ki x * y < MAX olana qədər.
void preprocess()
{
long long x = 1, y = 1;
while (x < MAX)
{
while (x * y < MAX)
{
v.push_back(x * y);
y *= 3;
}
x *= 2;
y = 1;
}Sayıları massivində sıralağın.
sort(v.begin(), v.end());
}Proqramın əsas hissəsi. 2^x * 3^y rəqəmləri massivini yaradırıq.
preprocess();Sorğunu oxuyuruq — intervalı. Bu intervalda axtarılan rəqəmlərin sayı aşağıdakı formada hesablanır:
while (scanf("%lld %lld", &a, &b) == 2)
{
res = upper_bound(v.begin(), v.end(), b) – upper_bound(v.begin(), v.end(), a - 1);
printf("%lld\n", res);
}