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;
}
posted @ 2025-05-28 13:28  usedchang  阅读(62)  评论(0)    收藏  举报