Project Euler Homework
|
00001 #include <iostream> 00002 using namespace std; 00003 00004 typedef unsigned long long verylong; 00005 class bigNmod 00006 { 00007 verylong A, B; 00008 public: 00009 bigNmod (unsigned k) 00010 { 00011 A = 0; 00012 B = k; 00013 } 00014 void square () 00015 { 00016 verylong newB = B * B; 00017 verylong newA = A * B * 2 + newB / 100000; 00018 A = newA % 100000; 00019 B = newB % 100000; 00020 } 00021 void times (unsigned y) 00022 { 00023 B *= y; 00024 A = (A * y + B / 100000) % 100000; 00025 B %= 100000; 00026 } 00027 verylong value () //return the value of N 00028 { 00029 return A * 100000 + B; 00030 } 00031 }; 00032 00033 unsigned 00034 small_term (unsigned k) //used to calculate small terms 00035 { 00036 unsigned answer = 1; 00037 for (int i = 1; i <= k; i++) 00038 answer *= k; 00039 return answer; 00040 } 00041 00042 unsigned 00043 reverse (unsigned k) //needed to calculate power 00044 { 00045 unsigned new_k = 1; //mark the end of binary string to be 1 00046 do 00047 { 00048 new_k <<= 1; 00049 if (k & 1) new_k++; 00050 k >>= 1; 00051 } 00052 while (k > 0); 00053 return new_k; 00054 } 00055 00056 verylong 00057 big_term (unsigned k) //used to calculate large terms 00058 { 00059 bigNmod answer (k); 00060 unsigned index = reverse (k); 00061 index >>= 1; 00062 do 00063 { 00064 answer.square (); 00065 if (index & 1) 00066 answer.times (k); 00067 00068 index >>= 1; //more efficient than index/=2 00069 } 00070 while (index > 1); //stop when the end bit has attained 00071 return answer.value (); 00072 } 00073 00074 int 00075 main () 00076 { 00077 verylong sum = 1; //the 1st term 00078 for (unsigned k = 2; k <= 9; k++) //2nd to 9th term 00079 sum += small_term (k); 00080 00081 for (unsigned k = 11; k <= 999; k++) //11th to 999th term 00082 { 00083 if (k % 10 == 0) 00084 continue; //exclude multiples of 10 00085 sum += big_term (k); 00086 } 00087 //verylong sum = big_term (11); 00088 cout << (sum % 10000000000ULL)<< endl; 00089 return 0; 00090 } 00091