Self Powers
The series, .
Find the last ten digits of the series, .
Implementations
// https://projecteuler.net/problem=48
// The series, 1¹ + 2² + 3³ + … + 10¹⁰ = 10405071317.
// Find the last ten digits of the series, 1¹ + 2² + 3³ + … + 1000¹⁰⁰⁰.
// Answer: 9110846700
// Authored by: Tim Varley 💘
#include <iostream>#include <string>
std::string self_powers() { const long long MOD = 10000000000LL; // 10^10 long long sum = 0; for (int i = 1; i <= 1000; ++i) { long long power = 1; for (int j = 0; j < i; ++j) { power = (power * i) % MOD; } sum = (sum + power) % MOD; } std::string result = std::to_string(sum); while (result.size() < 10) result = "0" + result; return result;}
#if ! defined UNITTEST_MODEint main(int argc, char const *argv[]) { std::cout << self_powers() << std::endl;}#endif // UNITTEST_MODESolution Notes
Mathematical Background
Self powers are numbers raised to their own power: n^n.
The series is S = 1^1 + 2^2 + 3^3 + … + 1000^1000.
We need the last ten digits of S, i.e., S mod 10^10.
Algorithm Analysis
Since we only need the last ten digits, we can compute each term modulo 10^10, then sum modulo 10^10.
For large exponents, we use modular exponentiation to compute n^n mod 10^10 efficiently.
Performance Analysis
- Time Complexity: O(1000 × log(10^10)) ≈ O(10^6)
- Space Complexity: O(1)
- Execution Time: Very fast (<1 second)
- Scalability: Linear in the upper limit
Key Insights
-
Modular arithmetic allows handling arbitrarily large numbers
-
The last ten digits depend only on the computation modulo 10^10
-
Efficient exponentiation prevents overflow
-
The sum grows very large, but we only need the residue
Educational Value
This problem teaches:
-
Modular arithmetic for large number computations
-
Efficient exponentiation algorithms
-
The concept of residues and last digits
-
Handling computational limits through mathematical techniques