哭瞎了。。想了这么几天原来是道暴搜题。。。之前思路就没错,广搜的时候不知道为什么爆掉了。。估计是内存没开下就以为很多。。。
就是如果a[i]*a[i]>left的时候,二分最大界j使得a[j]<=left,这一段一起统计就行了
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
class HolyNumbers {
public:
long long count(long long, int);
};
bool flag[1000050];
vector<long long> prime;
void pre(int n) {
int i, j;
memset(flag, true, sizeof(flag));
prime.clear();
for (i = 2; i <= n; ++i) {
if (flag[i]) {
prime.push_back(i);
for (j = 2; i * j <= n; ++j)
flag[i * j] = false;
}
}
}
long long dfs(int i, long long left) {
int up, down, mid;
long long ret, j;
if (i == prime.size())
return 0;
if (prime[i] > left)
return 0;
if (prime[i] * prime[i] > left) {
up = prime.size() - 1;
down = i;
while (up - down > 0) {
mid = (up + down + 1) / 2;
if (prime[mid] > left)
up = mid - 1;
else
down = mid;
}
return up - i + 1;
}
ret = 0;
ret += dfs(i + 1, left);
for (j = prime[i]; j <= left; j *= prime[i] * prime[i])
ret += dfs(i + 1, left / j) + 1;
return ret;
}
long long HolyNumbers::count(long long upTo, int maximalPrime) {
pre(maximalPrime);
return dfs(0, upTo) + 1;
}