18. 简单的数学题
单测试点时限: 1.0 秒
内存限制: 512 MB
定义: 函数 f(n) 为 n 的非质素的因子的个数。
输入
第一行一个数字 T;
接下来 T 行,每行一个数字 n。
1≤T≤3⋅106,1≤n≤2⋅106 。
输出
每行输出一个数字 f(n) 。
样例
input
3 1 6 12
output
1 2 4
提示
样例解释:12 的因子为 {1,2,3,4,6,12} ,其中非质素的因子为 {1,4,6,12} 。
本题输入输出量比较大,请尽量使用快速的OI方法。
思路:
由于T较大,n较小,不妨打表
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 5;
int prime[200005],pos = 0,ans[maxn];
bool check[maxn];
void init()
{
for (int i = 2;i < maxn;i ++)
if (!check[i])
{
prime[pos ++] = i;
for (int j = i + i;j < maxn;j += i)
check[j] = 1;
}
}
int solve(int n)
{
int ans = 1,y = 0;
for (int i = 0;prime[i] * prime[i] <= n;i ++)
{
int cnt = 0;
if (n % prime[i] == 0) y ++;
while (n % prime[i] == 0) cnt ++,n /= prime[i];
ans *= cnt + 1;
}
return n == 1 ? ans - y : 2 * ans - y - 1;
}
void pp()
{
for (int i = 1;i < maxn - 4;i ++)
ans[i] = solve(i);
}
int main()
{
int n,t;
init();
pp();
scanf("%d",&t);
while (t --)
{
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return 0;
}