At383 D - 9 Divisors
D.9 Divisors
题意简述
找到不大于N的数里恰好有9个因子的数的个数
解题思路
因为因子个数,所以想到算术基本定理,一个数可以分解为 \(p_1^{k_1}·p_2^{k_2}···p_n^{k_n}\)的形式,同时这个数因数的个数为 \((k_1+1)·(k_2+1)···(k_n+1)\),所以考虑找到小于n的所有满足 \(p^8\) \(p_i^2·p_j^2\) 的个数,对于第一种很好求,直接枚举因子就好,第二种我们想要求两个不相同且乘积小于 $ \sqrt n $ 的数,拿筛法预处理一下小于 $ \sqrt n$ 的素数,然后前缀和处理一下前缀素数的个数,枚举大于每个素数的另一个配对素数的个数,这样一定保证不重不漏。
AC code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const ll inf=1e18;
vector<char>isprime;
vector<int>prime;
void init(const int &n){
isprime.resize(n+1);
isprime[1]=1;
for(int i=2;i<=n;i++){
if(!isprime[i]) prime.push_back(i);
for(auto &p:prime){
if(p*i>=n) break;
isprime[i*p]=1;
if(i%p==0) break;
}
}
}
ll q_pow(ll a,ll b){
ll s=1;
while(b){
if(b&1){
s*=a;
}
a*=a;
b>>=1;
}
return s;
}
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
ll n;cin>>n;
ll sq_n=sqrtl(n+0.5);
init(sq_n+1);
ll ans=0;
for(auto &p:prime){
if(q_pow(p,8LL)>n) break;
ans++;
}
vector<ll>pre(sq_n+1);
for(int i=1;i<=sq_n;i++) pre[i]=pre[i-1]+(!isprime[i]);
for(auto &p:prime){
ll t=sq_n/p;
if(p>=t) break;
ans+=(pre[t]-pre[p]);
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号