am1x icon

erd001.cxx

am1x | PRO | 08/18/22 04:05:47 PM UTC (Edited) | 0 ⭐ | 1399 👁️ | Never ⏰ | []
C++ |

1.62 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <inttypes.h>
#include <endian.h>
#include <vector>
 
typedef unsigned int uint_t;
typedef long double real;
 
template<typename T> class Adder
{
    std::vector<T> v;
 
 public:
    void clear() {
        v.clear();
        v.push_back(0);
    }
 
    Adder() {
        clear();        
    }
 
    void add(T x) {
        size_t i = 0;
        for (i = 0; v[i]; i++) {
            x += v[i];
            v[i] = 0;
        }
        v[i] = x;
        if (i + 1 == v.size())
            v.push_back(0);
    }
 
    T value() {
        T res = v[0];
        size_t l = v.size();
        for (size_t i = 1; i < l; i++)
            res += v[i];
        return res;
    }
};
 
 
static void work(uint64_t n0, uint64_t n1)
{
    assert (n0 < n1);
    assert ((n1 - n0) % 2 != 0);
 
    Adder<real> s;
    uint64_t buf[2];
 
    for (uint64_t i = n0; i <= n1; i += 2) {
        size_t cnt = fread(buf, sizeof(buf[0]), 2, stdin);
        assert (cnt == 2);
        buf[0] = be64toh(buf[0]);
        buf[1] = be64toh(buf[1]);
//      fprintf(stderr, "p0=%" PRIu64 ", p1=%" PRIu64 "\n", buf[0], buf[1]);
        real p0 = buf[0], p1 = buf[1];
        real d = (p0 - (p1 - p0) * i) / (p0 * p1);
        s.add(d);
    }
    printf("%.24Lf\n", s.value());
 
}
 
 
 
 
int main(int ac, char **av)
{
    uint64_t as[2] = {0, 0};
    assert (ac == 3);
    for (uint_t i = 0; i < 2; i++) {
        char *eptr = 0;
        as[i] = strtoull(av[1 + i], &eptr, 0);
        if (as[i] == 0 || eptr == av[1 + i] || eptr == 0 || *eptr != 0) {
            fprintf(stderr, "wrong argument %u: '%s' \n", i, av[1 + i]);
        }
        fprintf(stderr, "as[%u] = %" PRIu64 " \n", i, as[i]);
    }
 
    assert (as[0] < as[1]);
    assert ((as[1] - as[0]) % 2 != 0);
 
    work(as[0], as[1]);
    
 
 
    return 0;
}
 
 
 

Comments