You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
2.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
// 60以内的质数列表
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
/*
思路:
如果是求n中为平方数的有多少个那么答案肯定是sqrt(n)
同理如果是三次根号的话答案是n的三分之一次方。
同理对于1e18次方的话最多就是2的64次方也就是说最多枚举大小不超过63的素数就可以了
还需要考虑一种情况比如说6的时候被素数2算了一遍然后又被素数3算了一遍这个地方会有重复的计算
又因为2^(3*5*7)已经超过2的60次方了所以我们只需要考虑三个质因子就可以了。
执行时间15MS
*/
signed main() {
int n;
while (cin >> n) {
int s = 1, t; // s=1表示最起码数字1符合要求
for (int i = 0; i < 17; i++) { // 三层循环遍历质数数组p枚举第一个因子
t = pow(n, 1.0 / primes[i]) - 1; // 计算出指数=p[i]的数的个数,需要减去1见下面的注释解释
if (!t) break; // 扣除完1^2后没有了那太白扯了
/*
int n = 10;
cout << (int)pow(n, 1.0 / 2) << endl;
输出3理解一下
10以内可以描述为x^2的有1^2 2^2 3^2
这样就是说上面的算法把数字1记录在内了。
*/
s += t; // t个
for (int j = i + 1; j < 17; j++) { // 三层循环,枚举第二个因子,避让第一个因子
t = pow(n, 1.0 / (primes[i] * primes[j])) - 1; // 计算出指数=p[i]*p[j]的数的个数
if (!t) break; // 扣除完1^2后没有了那太白扯了
s -= t; // 两个的要减
for (int k = j + 1; k < 17; k++) { // 三层循环,枚举第三个因子,避让第一、第二个因子
t = pow(n, 1.0 / (primes[i] * primes[j] * primes[k])) - 1; // 计算出指数=p[i]*p[j]*p[k]的数的个数
if (!t) break; // 扣除完1^2后没有了那太白扯了
s += t; // 三个的要加
}
}
}
cout << s << endl;
}
}