OJ-Problems-Source/QUSTOJ/1847_x7536110.cpp
2016-10-12 11:25:46 +08:00

62 lines
1.8 KiB
C++

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
namespace acm {
/// count primes between [1..n] (0< n <=1e9)
/// solution: dp
/// d(n, i) means that the number of value whose min prime number is bigger than i in [1..n]
/// d(n, i) = d(n, i-1) if number i is not a prime
/// d(n, i) = d(n, i-1) - d(n/i, i) + d(i, i-1) if number i is a prime
/// complex time: O(n^(3/4)), space: O(n^(1/2))
static const long long maxn = 1e6+11;
long long dp[maxn];
struct CountPrime {
long long solve(long long n) {
if (n < 2) {
return 0;
}
dp[0] = 0;
long long sqrtn = 1, length = 0;
for (; sqrtn <= n / sqrtn; ++sqrtn) {
dp[++length] = sqrtn - 1;
}
for (long long i = sqrtn - 1; i > 0; --i) {
long long val = n / i;
if (val != i) {
dp[++length] = val - 1;
}
}
for (long long i = 1; i < sqrtn; ++i) {
if (dp[i] == dp[i-1]) {
continue;
}
for (long long j=length; j>0; --j) {
long long val = j < sqrtn ? j : n / (length - j + 1);
if (i > val / i) {
break;
}
long long pre_statue_pos = val / i;
if (pre_statue_pos >= sqrtn) {
pre_statue_pos = length - n / pre_statue_pos + 1;
}
dp[j] += dp[i-1] - dp[pre_statue_pos];
}
}
return dp[length];
}
};
} // namespace acm
int main()
{
//freopen("in", "r", stdin);
//freopen("out", "w", stdout);
acm::CountPrime cp;
//printf("IIII\n");
long long n;
while (scanf ("%lld", &n) != EOF) {
printf ("%lld\n", cp.solve(n));
}
return 0;
}