zoukankan      html  css  js  c++  java
  • Project Euler Problem 543 Prime-Sum Numbers

    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,kn.

    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;
    }



  • 相关阅读:
    BZOJ3105:[CQOI2013]新Nim游戏(线性基,贪心)
    BZOJ5102:[POI2018]Prawnicy(贪心,堆)
    BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)
    BZOJ3569:DZY Loves Chinese II(线性基)
    BZOJ3534:[SDOI2014]重建(矩阵树定理)
    【BZOJ 1202】 [HNOI2005]狡猾的商人
    【BZOJ 1003】 [ZJOI2006]物流运输trans
    【BZOJ 2321】 [BeiJing2011集训]星器
    【BZOJ 1010】 [HNOI2008]玩具装箱toy
    【BZOJ 2730】 [HNOI2012]矿场搭建
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564006.html
Copyright © 2011-2022 走看看