Project Euler Problem 543 Prime-Sum Numbers
Problem 543
Define function P(n,k) = 1 if n can be written as the sum of k prime numbers (with repetitions allowed), and P(n,k) = 0 otherwise.
For example, P(10,2) = 1 because 10 can be written as either 3 + 7 or 5 + 5, but P(11,2) = 0 because no two primes can sum to 11.
Let S(n) be the sum of all P(i,k) over 1 ≤ i,k ≤ n.
For example, S(10) = 20, S(100) = 2402, and S(1000) = 248838.
Let F(k) be the kth Fibonacci number (with F(0) = 0 and F(1) = 1).
Find the sum of all S(F(k)) over 3 ≤ k ≤ 44
C++:
#include <iostream> #include <cstring> #include <cassert> using namespace std; //#define DEBUG const int FIBMAXN = 44; long fib[FIBMAXN+1]; void initfib(int n) { fib[0] = 0L; fib[1] = 1L; for(int i=2; i<=n; i++) fib[i] = fib[i-2] + fib[i-1]; } const int MAXN = 701408733; // fib(44) = 701408733 const int PCOUNT = 36322186; bool primeflag[MAXN]; long prime[PCOUNT]; int pcount; void esieve(int n) { memset(primeflag, true, sizeof(primeflag)); pcount = 0; for(long i=2; i<n; i++) { if(primeflag[i]) { for(long j = i * i ; j<n; j+=i) primeflag[j] = false; prime[pcount++] = i; } } } long pcounting(long n) { long lower = 0L; long upper = pcount - 1; long middle; while (lower <= upper) { middle = lower + (upper - lower) / 2; if (prime[middle] < n) lower = middle + 1; else if (prime[middle] == n) return middle + 1; else upper = middle - 1; } return lower; } long long s(long n) { long long sum = pcounting(n); if(n >= 4) sum += n / 2 -1; if(n >= 5) sum += pcounting(n - 2) - 1; if(n > 5) { long first_term = n - 6 + 1; long last_term = n - 2 * (n / 2) + 1; long term_count = (first_term - last_term) / 2 + 1; sum += (first_term + last_term) * term_count / 2; } return sum; } void solve() { long long sum = 0; for(int i=3; i<=FIBMAXN; i++) sum += s(fib[i]); cout << "Sum[S(F(k))](k=3..44) = " << sum << endl; } void benchmark() { assert(s(10) == 20); assert(s(100) == 2402); assert(s(1000) == 248838); } int main() { initfib(FIBMAXN); #ifdef DEBUG for(int i=0; i<=FIBMAXN; i++) cout << i << ": " << fib[i] << endl; #endif esieve(MAXN); #ifdef DEBUG cout << pcount << endl; benchmark(); #endif solve(); return 0; }