Calculate the square root of the sum of the squares of the prime factors of an input number
You can use the sieve approach to create an array of square sums. For any new prime that you sieve, you have:

sqsum[m * p] = sqsum[m] + p*p;


You can build that array as you go. The primes need a square sum value, too.

uint8_t sieve[RANGE] = {0};
uint64_t sqsum[RANGE] = {0};

void CalcAuxiliaryData()
{
    uint32_t i, j, k;

    for (i = 2; i &lt;= RANGE; i++) {
        if (sieve[i] == 0) {
            uint64_t ii = (uint64_t) i * i;

            sqsum[i] = ii;

            j = 2; 
            k = i + i;
            while (k &lt; RANGE) {
                sieve[k] = 1;
                sqsum[k] = sqsum[j++] + ii;
                k += i;
            }
        }
    }
}

uint32_t CalcDiagonalLen(uint32_t n)
{
    uint64_t square;
    uint32_t length;

    if (sieve[n] == 0) return n;

    square = sqsum[n];
    length = sqrt(square);
    if ((uint64_t) length * length == square) return length;

    return 0;
}


This approach adds more time to the initialisation, because you can't cut sieving short at sqrt(RANGE), but the sum lookup is fast.

You could also create a lookup array that tells you whether a number is a perfect square or not, but the sqrt function isn't the bottleneck here. And you could make the array itself a direct lookup table for the diagonal length.