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;
}
                    
                
                
            
        
浙公网安备 33010602011771号