I would like to iterate over the numbers with more than $D$ divisors in a large range $[x, x+N]$. Current values I'm working with are $D=626$ and $x\approx N\approx10^{11}.$
At the moment I'm using a factorization sieve (PARI/GP's forfactored) to iterate through the whole interval and skipping anything with at most $D$ divisors. (The factorization sieve computes the number of divisors 'for free'.)
If $D$ were really big, I might be able to restrict to multiples of 2, or 6, or 12. But even odd numbers this size can have over a thousand divisors, so that's not workable. But it seems like much better should be possible, since numbers with this many divisors are quite rare. There should be some solution which loops over exponents for the first few (100? 10000?) primes, but I'm not sure what stopping criteria to use. Thoughts?
I have written a script for this in C++, which you can find at the bottom of this answer. It seems it runs for your use case in $\approx 75$ seconds. It should be faster for you than
forfactored, please let me know if anyone finds any more optimisation that I can do to the code.I took your idea of looping over exponents, but in a reverse way (largest prime to lowest prime); and my stopping criteria uses 'Highly composite numbers', i.e., numbers $n$ where $d(n)$, the number of divisors of $n$ , increases to a record. See https://oeis.org/A002182 and https://oeis.org/A002183 for more explanation.
My script finds numbers in $[1,N]$ with divisors more than $D$. The high level idea is:
Run linear time sieve till $\left\lceil\sqrt N\right\rceil$, to find the prime numbers in $\left[2,\left\lceil\sqrt N\right\rceil\right]$. Let them be $p_1,p_2 \dots p_k$
Call recursive function
solve(k, 1, 1)Details of
solve(ind, val, divisors)are:If
ind = 0(terminating step) : OUTPUT(val) only ifdivisors$> D$Else find the largest value of A002182 $\le \frac{N}{\text{val}}\ = $ A002182[i]. Also find the corresponding A002183[i]
If A002183[i] $\times$
divisors$>D$, run a loop $t$ for exponents $p_\text{ind}^0, p_\text{ind}^1,p_\text{ind}^2,\dots p_\text{ind}^s \le \frac{N}{\text{val}}$ and callsolve(k-1, val * (p_ind)^t, divisors*(t+1)). This is the stopping criteria currently, and weeds out any possibilities which can't make it to more than $D$ divisors.The runtime complexity of this is somewhere between $\Omega(\sqrt N)$ and $O(N)$, and definitely depends highly on $D$ (where on high $D$, its closer to $\Theta(\sqrt N)$), but I have no idea currently how it depends on that. I'm running some time tests to get some idea, will edit the post if I get it.
Here are the current results :
Rows represent $N$ with values :
1000,10000,100000, ... 1000000000,10000000000Columns represent D with values :
100,200,300,400, ... 1800,1900,2000Finally the code: