- 原题链接:https://nanti.jisuanke.com/t/30999
- 题意:对于一个正整数n,f(n)表示有几个这样的等式 n = a*b,其中a和b都不能包含平方数,即a和b中的质因子数不能出现超过一次。其中 n = a*b 和n = b*a算作两个(a ≠ b). 现求 f(1)+……+f(n)。
- 思路 :此题需要以下两个知识点作为知识前提 (当然你可能没看过定理但是懂得基本含义):
1、算数基本定理 :每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。 即 x=p1^k1*p2^k2*p3^k3…pn^kn。
2、 欧拉筛法(也即线性筛法),可以参考博客
https://blog.csdn.net/qq_39763472/article/details/82428602
通过第一个定理,可以将问题转化成对n的素因子个数的讨论;而通过讨论素因子,便需要用到欧拉筛法,毕竟本题2e7的数据,也只有线性筛hold得住。
可以分以下情况讨论
1)若n是素数,则f(n) = 2
2) 若n的某个质因子个数超过2,则f(n) = 0。因为 n = a*b,若某个质因子个数超过2,那么a和b中必有一个它的平方
3) 若n的某个质因子个数为2,则f(n) = f(n/这个质因子的平方)。因为若使a和b中的此质因子个数都不为2,则a和b中各自有这个质因子,相当于贡献为0,则从n中消去此项即可。
4)若gcd(a,b) = 1,则 f(n) = f(a) * f(b).
- 代码 :
#include "bits/stdc++.h"
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define fori(i,l,u) for(int i = l;i < u;i++)
#define forj(j,l,u) for(int j = l;j < u;j++)
#define pb push_back
#define mk make_pair
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<string,int> ps;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;
const int maxn = 2e7+ 5;
int f[maxn];
int n;
int prime[maxn];
int visit[maxn];
void init(){ //线性筛法
mem(visit,0);
mem(prime,0);
f[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!visit[i]) { // i是素数的情况
prime[++prime[0]] = i; //纪录这个素数,其中prime[0]相当于cnt = 0,cnt++
f[i] = 2; //如果i 是素数,则f[i] = 2
}
for (int j = 1; j <= prime[0] && i*prime[j] < maxn; j++) {
int ans = i*prime[j];
visit[ans] = 1; // i*prime[j]是合数
if (i%prime[j] != 0) { //如果 gcd(i,prime[j]) == 1,那么 f(i*prime[j]) = f(i)*f(prime[j])
f[ans] = f[i] * f[prime[j]];
}
else{ //如果 prime[j]是i的质因子
if (i %(prime[j]*prime[j]) == 0) { //如果 ans 中prime[j]这个质因子个数超过2,则f[ans] = 0;
f[ans] = 0;
}
else{ //如果ans中有两个prime[j],则 结果为 f[ans/(prime[j]*prime[j])] 即 f[i]/2
f[ans] = f[ans/(prime[j]*prime[j])];
}
break;
}
}
}
for (int i = 1; i < maxn; i++) { //求前缀和
f[i] += f[i-1];
}
}
void solve(){
init();
int t;
cin>>t;
while (t--) {
int n;
cin>>n;
cout<<f[n]<<endl;
}
}
int main()
{
solve();
return 0;
}
可以和欧拉筛法比较一下,就是在其框架上加上了对ans的质因子个数分情况讨论。本题的核心便是对n质因子个数分情况讨论。