Skip to main content
1 of 4
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308

The obvious with this code is the lack of structure. There are two main computations, given that we've already spotted that we can add all the exponents and perform a single exponentiation with the sum:

  • Finding the Lth and Rth odd-length palindromic numbers
  • Modular exponentiation

Each of these should be separate - independently testable - functions; main() then only needs to read input, call the functions and print output.


Let's look at the exponentiation first. Putting your code into a function with reasonable names gives

long modexp(int base, int power, int modulus)
{
    long product = 1;
    for (int j = 1;  j <= power;  ++j)
        product = product * base % modulus;
    return product;
}

This is pretty slow, as it has to perform power multiplications. It's better to implement a binary exponentiaton, which scales as the log of the power:

long modexp(int base, int power, int modulus)
{
    long product = 1;
    while (power) {
        if (power % 2) {
            product = product * base % modulus;
        }
        base = 1L * base * base % modulus;
        power /= 2;
    }
    return product;
}

With that first easy win under our belt, let's turn our attention to the palindromes.

We don't need to iterate through all the possible palindromes. The pattern is quite simple: for a given number n, the n th odd-length palindrome is simply n followed by the reverse of n/10.

That's quite easy to compute without iterating:

int odd_palindrome(int n)
{
    int palindrome = n;
    while ((n /= 10)) {
        palindrome = palindrome * 10 + n % 10;
    }
    return palindrome;
}

We can now create a function to calculate the required function of the sequence of palindromes:

long compute_result(int left, int right)
{
    int sum = 0;
    for (int i = left + 1;  i <= right;  ++i) {
        sum += odd_palindrome(i);
    }
    return modexp(odd_palindrome(left), sum, 1000000007);
}

Having tested these functions, we can put it all together, getting something which is more efficient and easier to follow than the posted code:

#include <stdio.h>

const int result_modulus = 1000000007;

static long modexp(long base, int power, int modulus)
{
    long product = 1;
    while (power) {
        if (power % 2) {
            product = product * base % modulus;
        }
        base = base * base % modulus;
        power /= 2;
    }
    return product;
}

static int odd_palindrome(int n)
{
    int palindrome = n;
    while ((n /= 10)) {
        palindrome = palindrome * 10 + n % 10;
    }
    return palindrome;
}

static long compute_result(int left, int right)
{
    int sum = 0;
    for (int i = left + 1;  i <= right;  ++i) {
        sum += odd_palindrome(i);
    }
    return modexp(odd_palindrome(left), sum, result_modulus);
}

int main(void)
{
    int ntests;
    if (scanf("%d", &ntests) != 1) {
        return 1;
    }

    while (ntests --> 0) {
        int left, right;
        if (scanf("%d %d", &left, &right) != 2) {
            return 1;
        }
        printf("%ld\n", compute_result(left, right));
    }
}
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308