题意:(square-free integer )无平方整数是除了1以外不被其它整数的平方除的数.
一个数n = ab,问你有多少个a,b的组合,a,b都是无平方整数,用f(n)表示,让你求
思路:首先需明白欧拉筛,利用欧拉筛来求解每个的f(i)。
①欧拉筛首先是确定是否为素数,如果为素数,那么f(i)肯定就只有两个((1,i),(i,1))。
②然后欧拉筛就利用素数来筛去非素数,筛的每一步都是筛掉 i * primes[j], 那么这里就对 i*primes[j] 进行判断。
分为以下情况
Ⅰ 如果i%primes[j] != 0 那么i不是priems[j]的倍数,那么dp[i*priems[j]] = dp[i] * dp[primes[j]] ;不用考虑因数的限制,就是它们的组合。
Ⅱ 如果i%primes[j] ==0 ** ,那么这时候就需要考虑i里面有几个priems[j]了,
如果 i%(primes[j] * primes[j])==0**,那么i * prime[j]里面肯定有大于等于三个的primes[j],所以无论怎么分给a和b,都不满足条件,于是可以得出
dp[i] = 0;
但如果知识 i%primes[j] ==0 那么i * primes[j]里面只有两个primes[j],那么这时a和b中就各分一个primes[j],其实就是求dp[i/primes[j]]的个数了。
即dp[i] = dp[i/primes[j]];
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e7 + 5;
typedef long long ll;
ll dp[maxn];
bool vis[maxn];
ll primes[maxn];
ll cnt;
void solve_num(){
//memset(dp,1,sizeof(dp));错误了,memset是依靠二进制进行初始化的所以只能赋值为0
dp[1] = 1;
for(ll i = 2 ;i < maxn;i++){
if(!vis[i]){
primes[cnt ++] = i;
dp[i] = 2;
}
for(ll j = 0 ; i * primes[j] < maxn ; j++){
vis[i * primes[j]] = true;
if(i % primes[j] != 0){
dp[i*primes[j]] = dp[i] * dp[primes[j]];
}
else{
if(i % (primes[j]*primes[j]) == 0 ){
dp[i * primes[j]] = 0;
}
else{
dp[i * primes[j]] = dp[i/primes[j]];
}
break;
}
}
}
for(int i =1;i<maxn;i++){
dp[i] += dp[i-1];
}
}
int main(){
solve_num();
ll t,n;
cin>>t;
ll ans;
while(t--){
ans = 0;
cin>>n;
cout<<dp[n]<<endl;
}
return 0;
}
(emmmm,欧拉筛还能这样用的,第一次遇见)
如果有什么错的话,请提出来嘿嘿嘿嘿