Having tested these functions, we can put it all together (using types that are guaranteed large enough to represent the expected range of values), getting something which is more efficient and easier to follow than the posted code:
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
typedef uint_fast32_t u32;
typedef uint_fast64_t u64;
const intu32 result_modulus = 1000000007;
static longu64 modexp(longu64 base, intu64 power, intu32 modulus)
{
longu64 product = 1;
while (power) {
if (power % 2) {
product = product * base % modulus;
}
base = base * base % modulus;
power /= 2;
}
return product;
}
static intu32 odd_palindrome(intu32 n)
{
intu32 palindrome = n;
while ((n /= 10)) {
palindrome = palindrome * 10 + n % 10;
}
return palindrome;
}
static longu64 compute_result(intu32 left, intu32 right)
{
intu64 sum = 0;
for (intu32 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) {
intu32 left, right;
if (scanf("%d"%"SCNuFAST32" %d"%"SCNuFAST32, &left, &right) != 2) {
return 1;
}
printf("%ld\n""%"PRIuFAST64"\n", compute_result(left, right));
}
}