题解:AT_abc383_d [ABC383D] 9 Divisors

个人认为官方题解讲的不太细致,所以这篇题解我们来解决里面的问题。

首先,在官方题解说:我们很容易发现答案就是这样的式子:

pp 为单调递增的质数序列,nn 为其大小,a=pia=p_ib=pjb=p_j

则答案为:

i=1n[a8n]+i=1nj=i+1n[a2b2n]\sum_{i = 1}^{n}[a^8 \le n] + \sum_{i = 1}^{n}\sum_{j = i + 1}^{n}[a^2b^2 \le n]

那为什么呢?

先来看前半部分,一个数是一个质数 aa88 次方,由于整数唯一分解定理,其所有因数就是 1,a,a2,a3a81,a,a^2,a^3\dots a^8,正好 99 个。

再看后半部分,a2b2a^2b^2 的全部因数有:1,a,b,a2,b2,ab,a2b,ab2,a2b21,a,b,a^2,b^2,ab,a^2b,ab^2,a^2b^2,也是 99 个。

然后就好啦!注意不要溢出。

#include<bits/stdc++.h>
using namespace std;
long long n,  vis[1000005], p[1000005], cnt, ans;
void prime(){
    int len = 1e6;//筛 1e6 内的质数
	for(int i = 2; i <= len; i ++){
		if(!vis[i]){
			p[++ cnt] = i ;
		}
		for(int j = 1; p[j] * i <= len; j ++){
			vis[i * p[j]] = 1;
			if(i % p[j] == 0) break;
		}
	}
}
int main(){
    cin >> n;
    prime();
    for(int i = 1; i <= cnt; i ++){
        if(p[i] * p[i] * p[i] * p[i] > n) break;//两个式子的值都大于它,它爆了其它的也要爆
        if(p[i] <= 100 && p[i] * p[i] * p[i] * p[i] * p[i] * p[i] * p[i] * p[i] <= n){//p[i] > 100 可能会爆 long long
            ans ++;
        }
        for(int j = i + 1; j <= cnt; j ++){
            if(p[i] * p[i] * p[j] * p[j] <= n){
                ans ++;
            }
            else break;//大了就没必要找了
        }
    }
    cout << ans;
	return 0;
}

posted on 2024-12-08 10:09  zhangzirui66  阅读(10)  评论(0)    收藏  举报  来源

导航