题目链接:

https://projecteuler.net/problem=501

题意:

\(f(n)\) be the count of numbers not exceeding \(n\) with exactly eight divisors.

就是找少于等于 \(n\)中只有8个因子的个数。

You are given \(f(100) = 10, f(1000) = 180\) and \(f(10^6) = 224427\).

Find \(f(10^{12})\)

题解:

我们知道,对于 \(n=\prod p_i^{a_i}\) ,那么,\(n\)的因子的个数有 \(\prod (a_i+1)\)个。

那么,符合题目条件的只有三种情况。

\(1.p^{7} <= n\)

\(2.p^{3} * q <= n\)

\(3.p * q * r <= n\)'

其中,\(p,q,r\)是各自不相等的质数,并且 \(p < q < r\)。

和这题套路一样。

http://codeforces.com/problemset/problem/665/F

Codefores这题代码:

#include <bits/stdc++.h>
using namespace std; const int MAX = 2e6+5;
const int M = 7;
typedef long long ll;
vector<int> lp, primes, pi;
int phi[MAX+1][M+1], sz[M+1]; void factor_sieve()
{
lp.resize(MAX);
pi.resize(MAX);
lp[1] = 1;
pi[0] = pi[1] = 0;
for (int i = 2; i < MAX; i++) {
if (lp[i] == 0) {
lp[i] = i;
primes.emplace_back(i);
}
for (int j = 0; j < primes.size() && primes[j] <= lp[i]; j++) {
int x = i * primes[j];
if (x >= MAX) break;
lp[x] = primes[j];
}
pi[i] = primes.size();
}
} void init()
{
factor_sieve();
for(int i = 0; i <= MAX; i++) {
phi[i][0] = i;
}
sz[0] = 1;
for(int i = 1; i <= M; i++) {
sz[i] = primes[i-1]*sz[i-1];
for(int j = 1; j <= MAX; j++) {
phi[j][i] = phi[j][i-1] - phi[j/primes[i-1]][i-1];
}
}
} int sqrt2(long long x)
{
long long r = sqrt(x - 0.1);
while (r*r <= x) ++r;
return r - 1;
} int cbrt3(long long x)
{ long long r = cbrt(x - 0.1);
while(r*r*r <= x) ++r;
return r - 1;
} long long getphi(long long x, int s)
{
if(s == 0) return x;
if(s <= M)
{
return phi[x%sz[s]][s] + (x/sz[s])*phi[sz[s]][s];
}
if(x <= primes[s-1]*primes[s-1])
{
return pi[x] - s + 1;
}
if(x <= primes[s-1]*primes[s-1]*primes[s-1] && x < MAX)
{
int sx = pi[sqrt2(x)];
long long ans = pi[x] - (sx+s-2)*(sx-s+1)/2;
for(int i = s+1; i <= sx; ++i) {
ans += pi[x/primes[i-1]];
}
return ans;
}
return getphi(x, s-1) - getphi(x/primes[s-1], s-1);
} long long getpi(long long x)
{
if(x < MAX) return pi[x];
int cx = cbrt3(x), sx = sqrt2(x);
long long ans = getphi(x, pi[cx]) + pi[cx] - 1;
for(int i = pi[cx]+1, ed = pi[sx]; i <= ed; i++)
{
ans -= getpi(x/primes[i-1-1]) - i + 1;
}
return ans;
} long long lehmer_pi(long long x)
{
if(x < MAX) return pi[x];
int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
int b = (int)lehmer_pi(sqrt2(x));
int c = (int)lehmer_pi(cbrt3(x));
long long sum = getphi(x, a) + (long long)(b + a - 2) * (b - a + 1) / 2;
for (int i = a + 1; i <= b; i++)
{
long long w = x / primes[i-1];
sum -= lehmer_pi(w);
if (i > c) continue;
long long lim = lehmer_pi(sqrt2(w));
for (int j = i; j <= lim; j++)
{
sum -= lehmer_pi(w / primes[j-1]) - (j - 1);
}
}
return sum;
} long long power(long long a, long long b)
{
long long x = 1, y = a;
while(b)
{
if (b&1) x = x * y;
y = y * y;
b >>= 1;
}
return x;
}
void solve(long long n)
{
ll ans = 0;
// case 1: p^3 <= n ,p is a prime
for(int i = 0; i < (int)primes.size(); i++) {
if (power(primes[i], 3) <= n) {
//std::cout << primes[i] << '\n';
ans += 1;
}
else {
break;
}
}
// std::cout << "ans=" <<ans << '\n'<<'\n';
// case 2: p*q <= n (p < q)
// p, q is distinct primes
ll cnt = 0;
ll q = 0;
for(int i = 0; i < (int)primes.size(); i++) //p
{
ll x = (ll)primes[i]; // p
q = n / x; //q
if(q <= x)continue;
if(q == 0)continue;
//std::cout << "p=" << x << '\n';
//std::cout << "q=" << q << '\n';
cnt = lehmer_pi(q);
if (q >= primes[i]) {
cnt -= lehmer_pi(x);
}
if (cnt <= 0) break;
//std::cout << "cnt=" <<cnt << '\n';
ans += cnt;
}
// std::cout << "p*q finish!" << '\n'; std::cout << ans << '\n';
}
int main(int argc, char const *argv[])
{
ll n;
init();
scanf("%lld", &n);
solve(n);
return 0;
}

PE501代码:

利用 Lucy_Hedgehog's method. \(O(n^{3/4})\)。跑10min左右...太慢了..

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2000010;
vector<int> mark,prime;
void init()
{
mark.resize(maxn);
mark[1] = 1;
for (int i = 2; i < maxn; i++)
{
if (mark[i] == 0)
{
mark[i] = i;
prime.emplace_back(i);
}
for (int j = 0; j < (int)prime.size() && prime[j] <= mark[i]; j++)
{
int x = i * prime[j];
if (x >= maxn) break;
mark[x] = prime[j];
}
}
}
ll check(ll v, ll n, ll ndr, ll nv) {
return v >= ndr ? (n / v - 1) : (nv - v);
}
ll primenum(ll n) // O(n^(3/4))
{
assert(n>=1);
ll r = (ll)sqrt(n);
ll ndr = n / r;
assert(r*r <= n && (r+1)*(r+1) > n);
ll nv = r + ndr - 1;
std::vector<ll> S(nv+1);
std::vector<ll> V(nv+1);
for(ll i=0;i<r;i++) {
V[i] = n / (i+1);
}
for(ll i=r;i<nv;i++) {
V[i] = V[i-1] - 1;
}
for(ll i = 0;i<nv;i++) {
S[i] = V[i] - 1; //primes number
}
for(ll p=2;p<=r;p++) {
if(S[nv-p] > S[nv-p+1]) {
ll sp = S[nv-p+1]; // sum of primes smaller than p
ll p2 = p*p;
// std::cout << "p=" << p << '\n'; // p is prime
for(ll i=0;i<nv;i++) {
if(V[i] >= p2) {
S[i] -= 1LL * (S[check(V[i] / p, n, ndr, nv)] - sp);
}
else break;
}
}
}
ll ans = S[0];
return ans;
} ll qpower(ll a, ll b)
{
ll res = 1;
while(b)
{
if (b&1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
} void solve(ll n)
{ ll ans = 0;
// case 1: p^7 <= n ,p is a prime
for(int i = 0; i < (int)prime.size(); i++) {
// for example 2^7 = 128 <=n
if (qpower(prime[i], 7) <= n) {
//std::cout << primes[i] << '\n';
ans += 1;
}
else {
break;
}
}
std::cout << "p^7 finish!" << '\n'; // case 2: p^3*q <= n (p < q)
// p, q is distinct primes
ll cnt = 0;
for(int i = 0; i < (int)prime.size(); i++) //p
{
ll x = (ll)prime[i]*prime[i]*prime[i]; // p^3
x = n / x; //q
if(x == 0)continue;
cnt = primenum(x);
if (x >= prime[i]) {
cnt -= 1;
}
if (cnt <= 0) break;
ans += cnt;
}
std::cout << "p^3*q finish!" << '\n'; //case 3: p*q*r <= n (p < q < r)
// p,q,r is distinct primes
for(int i = 0; i < (int)prime.size(); i++) // p
{
if (qpower(prime[i], 3) > n) {
break;
}
for(int j = i+1; j < (int)prime.size(); j++) // q
{
ll x = n / ((ll)prime[i]*prime[j]);
if(x <= j)continue;
if(x == 0)continue;
cnt = primenum(x); // r
cnt -= j+1;
if (cnt <= 0) break;
ans += cnt;
}
}
std::cout << "p*q*r finish!" << '\n';
std::cout << ans << '\n';
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
}
int main(int argc, char const *argv[])
{
/* code */
init();
solve(100);
solve(1000);
solve(1000000);
solve(1e12);
return 0;
}

利用Meisell-Lehmer's method。\(O(n^{2/3})\)。跑10s..

#include <bits/stdc++.h>
using namespace std; const int MAX = 2e6+5;
const int M = 7; vector<int> lp, primes, pi;
int phi[MAX+1][M+1], sz[M+1]; void factor_sieve()
{
lp.resize(MAX);
pi.resize(MAX);
lp[1] = 1;
pi[0] = pi[1] = 0;
for (int i = 2; i < MAX; i++) {
if (lp[i] == 0) {
lp[i] = i;
primes.emplace_back(i);
}
for (int j = 0; j < primes.size() && primes[j] <= lp[i]; j++) {
int x = i * primes[j];
if (x >= MAX) break;
lp[x] = primes[j];
}
pi[i] = primes.size();
}
} void init()
{
factor_sieve();
for(int i = 0; i <= MAX; i++) {
phi[i][0] = i;
}
sz[0] = 1;
for(int i = 1; i <= M; i++) {
sz[i] = primes[i-1]*sz[i-1];
for(int j = 1; j <= MAX; j++) {
phi[j][i] = phi[j][i-1] - phi[j/primes[i-1]][i-1];
}
}
} int sqrt2(long long x)
{
long long r = sqrt(x - 0.1);
while (r*r <= x) ++r;
return r - 1;
} int cbrt3(long long x)
{ long long r = cbrt(x - 0.1);
while(r*r*r <= x) ++r;
return r - 1;
} long long getphi(long long x, int s)
{
if(s == 0) return x;
if(s <= M)
{
return phi[x%sz[s]][s] + (x/sz[s])*phi[sz[s]][s];
}
if(x <= primes[s-1]*primes[s-1])
{
return pi[x] - s + 1;
}
if(x <= primes[s-1]*primes[s-1]*primes[s-1] && x < MAX)
{
int sx = pi[sqrt2(x)];
long long ans = pi[x] - (sx+s-2)*(sx-s+1)/2;
for(int i = s+1; i <= sx; ++i) {
ans += pi[x/primes[i-1]];
}
return ans;
}
return getphi(x, s-1) - getphi(x/primes[s-1], s-1);
} long long getpi(long long x)
{
if(x < MAX) return pi[x];
int cx = cbrt3(x), sx = sqrt2(x);
long long ans = getphi(x, pi[cx]) + pi[cx] - 1;
for(int i = pi[cx]+1, ed = pi[sx]; i <= ed; i++)
{
ans -= getpi(x/primes[i-1-1]) - i + 1;
}
return ans;
} long long lehmer_pi(long long x)
{
if(x < MAX) return pi[x];
int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
int b = (int)lehmer_pi(sqrt2(x));
int c = (int)lehmer_pi(cbrt3(x));
long long sum = getphi(x, a) + (long long)(b + a - 2) * (b - a + 1) / 2;
for (int i = a + 1; i <= b; i++)
{
long long w = x / primes[i-1];
sum -= lehmer_pi(w);
if (i > c) continue;
long long lim = lehmer_pi(sqrt2(w));
for (int j = i; j <= lim; j++)
{
sum -= lehmer_pi(w / primes[j-1]) - (j - 1);
}
}
return sum;
} long long power(long long a, long long b)
{
long long x = 1, y = a;
while(b)
{
if (b&1) x = x * y;
y = y * y;
b >>= 1;
}
return x;
}
void solve(long long n)
{
init();
long long ans = 0, val = 0; // case : p^7 <= n ,p is a prime
for(int i = 0; i < primes.size(); i++) {
// for example 2^7 = 128 <=n
if (power(primes[i], 7) <= n) {
//std::cout << primes[i] << '\n';
ans += 1;
}
else {
break;
}
}
// std::cout << "ans = " << ans << '\n'; // case : p^3*q <= n (assume q > p for finding unique pairs)
// p, q is distinct primes
for(int i = 0; i < primes.size(); i++) //p
{
long long x = (long long)primes[i]*primes[i]*primes[i]; // p^3
x = n / x; //q
val = lehmer_pi(x);
if (x >= primes[i]) {
val -= 1;
}
if (val <= 0) break;
ans += val;
}
//case : p*q*r <= n (assume r > q > p for finding unique pairs)
// p,q,r is distinct primes
for(int i = 0; i < primes.size(); i++) // p
{
if (power(primes[i], 3) > n) {
break;
}
for(int j = i+1; j < primes.size(); j++) // q
{
long long x = n / ((long long)primes[i]*primes[j]);
if(x < j)continue;
val = lehmer_pi(x); // r
val -= j+1; // 减去 计算 <=x 的素数个数中多余的
if (val <= 0) break;
ans += val;
}
}
std::cout << ans << '\n';
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
}
int main(int argc, char const *argv[])
{
/* code */
solve(1e12);
return 0;
}

Project Euler 501 Eight Divisors (数论)的更多相关文章

  1. Project Euler 516 5-smooth totients (数论)

    题目链接: https://projecteuler.net/problem=516 题目: \(5\)-smooth numbers are numbers whose largest prime ...

  2. Python练习题 048:Project Euler 021:10000以内所有亲和数之和

    本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...

  3. Python练习题 040:Project Euler 012:有超过500个因子的三角形数

    本题来自 Project Euler 第12题:https://projecteuler.net/problem=12 # Project Euler: Problem 12: Highly divi ...

  4. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  5. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  6. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  7. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  8. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  9. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

随机推荐

  1. QQ,新浪,SNS等公众平台的登录及api操作

    QQ的写法地址:http://www.oschina.net/code/snippet_930167_19888 Sina的写法地址:http://www.oschina.net/code/snipp ...

  2. 五十个UI设计资源网站

    五十个UI设计资源网站 用户体验团队网站 1.UCD大社区 http://ucdchina.com/ 2.腾讯WSD http://wsd.tencent.com/ 3.腾讯CDC http://cd ...

  3. OCP-1Z0-051-题目解析-第27题

    27. Which two statements are true regarding tables? (Choose two.)  A. A table name can be of any len ...

  4. docker on spark

    从docker 仓库 pull 镜像 docker pull sequenceiq/spark:1.4.0 构建 docker 镜像 docker build –rm -t sequenceiq/sp ...

  5. Android自己定义视图(一):带下划线的TextView

    package com.francis.underlinetextviewtest; import android.content.Context; import android.content.re ...

  6. vue ---- 实现手机端(左滑 删除。右划 正常)

    touchstart: // 手指放到屏幕上的时候触发 touchmove: // 手指在屏幕上移动的时候触发 touchend: // 手指从屏幕上拿起的时候触发 touchcancel: // 系 ...

  7. 浏览器加载跟渲染html的顺序-css渲染效率的探究

    1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...

  8. 分享一个关于js原型链的理解

    http://www.cnblogs.com/wyaocn/p/5815761.html

  9. Spark 1.6.1 源码分析

    由于gitbook网速不好,所以复制自https://zx150842.gitbooks.io/spark-1-6-1-source-code/content/,非原创,纯属搬运工,若作者要求,可删除 ...

  10. 【习题 8-9 1613】 K-Graph Oddity

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 感觉最大度数|1就是最多需要的个数了. 就贪心一下. 然后模拟染色的过程就可以了. (贪心染色就可以了 (看看周围哪个颜色没有,就用 ...