|
发表于 2021-3-4 21:12:05
|
显示全部楼层
本帖最后由 guosl 于 2021-3-4 21:21 编辑
答案:1517926517777556(用时:4.18425秒)
要用高精度数值计算和一次同余方程解的理论来求。如果要加快计算速度还可以用平行编程来实现。
- #include <iostream>
- #include <stack>
- #include <vector>
- #include <algorithm>
- #include <gmp.h>
- #include <gmpxx.h>
- #include <omp.h>
- using namespace std;
- const int nN = 50000000;
- const mpz_class MOD = mpz_class("4503599627370517");
- const mpz_class uEu = mpz_class("1504170715041707");
- struct stNode
- {
- unsigned long long v;
- unsigned long long n;
- bool operator<(const stNode &nd) const
- {
- return (n < nd.n);
- }
- };
- stack<stNode> sk;
- vector<stNode> nd;
- mpz_class qpow(mpz_class a, mpz_class p)
- {
- if (p == 1)
- return a;
- mpz_class r;
- if (p % 2 == 0)
- {
- r = qpow(a, p / 2);
- r *= r;
- }
- else
- {
- r = qpow(a, p - 1);
- r *= a;
- }
- r %= MOD;
- return r;
- }
- int main(void)
- {
- double t = omp_get_wtime();
- nd.resize(nN);
- nd[0].v = uEu.get_ui();
- nd[0].n = 1;
- sk.push(nd[0]);
- unsigned long long pp;
- int kk;
- mpz_class u = qpow(uEu, MOD - 2);
- #pragma omp parallel shared(nd,pp,kk,u)
- {
- #pragma omp for
- for (int i = 0; i < nN; ++i)
- {
- mpz_t integ;
- mpz_init(integ);
- mpz_mul_si(integ, uEu.get_mpz_t(), i + 1);
- mpz_mod(integ, integ, MOD.get_mpz_t());
- nd[i].v = mpz_get_ui(integ);
- mpz_clear(integ);
- nd[i].n = (i + 1);
- }
- #pragma omp single
- {
- for (int i = 0; i < nN; ++i)
- {
- stNode &d = sk.top();
- if (nd[i].v < d.v)
- sk.push(nd[i]);
- }
- pp = nd[nN - 1].n;
- kk = sk.top().v;
- nd.clear();
- nd.resize(kk);
- }
- #pragma omp for
- for (int i = 1; i < kk; ++i)
- {
- mpz_t integ;
- mpz_init(integ);
- mpz_mul_si(integ, u.get_mpz_t(), i);
- mpz_mod(integ, integ, MOD.get_mpz_t());
- nd[i - 1].n = mpz_get_ui(integ);
- mpz_clear(integ);
- nd[i - 1].v = i;
- }
- }
- sort(nd.begin(), nd.end());
- for (int i = 0; i < (int)nd.size(); ++i)
- {
- if (nd[i].n > pp && nd[i].v < sk.top().v)
- sk.push(nd[i]);
- }
- unsigned long long Sum = 0;
- while (!sk.empty())
- {
- Sum += sk.top().v;
- sk.pop();
- }
- t = omp_get_wtime() - t;
- cout << Sum << endl << t << endl;
- return 0;
- }
复制代码 |
|