牛客寒假集训营第二场I牛牛的“质因数”
牛牛的“质因数”
https://ac.nowcoder.com/acm/contest/9982/I
前言
昨天是用分段打表过的,看了题解发现可以利用埃氏筛法,感觉还是有一定思维量的。
题目链接
题解
在埃氏筛法中,每个合数都有一个质数以及他的倍数筛出,也就是,其中是质数,自然是的倍数。并且这里的是从小到大枚举的,刚好符合题意。
当枚举到质因子时,若中还包含个质因子,那我们总共需要将个连接起来,也就是,需要注意的是,这里的是针对个位数的质因子而言。比如这种不止一位数的因子,我们需要。
代码
/* * @Author: hesorchen * @Date: 2020-11-26 09:12:46 * @LastEditTime: 2021-02-04 11:09:41 * @Description: 栽种绝处的花 */ #include <bits/stdc++.h> using namespace std; const long long mod = 1000000007; bool vis[4000010]; long long dp[4000010]; long long get(long long x) { long long res = 1; while (x) { x /= 10; res *= 10; } return res; } void pre() { for (long long i = 2; i <= 4e6; i++) { if (!vis[i]) { dp[i] = i; long long len = get(i); //不同位数需要乘不同数量的10 for (long long j = 2; i * j <= 4e6; j++) { vis[i * j] = 1; dp[i * j] = dp[i * j] * len % mod + i % mod; //连上一个i if (j % i == 0) { long long cnt = 0, jj = j; while (jj % i == 0) //j里边包含cnt个i,都需要连上 jj /= i, cnt++; for (long long k = 1; k <= cnt; k++) dp[i * j] = (dp[i * j] * len % mod + i) % mod; } } } } } int main() { long long n; cin >> n; pre(); long long out = 0; for (long long i = 2; i <= n; i++) out = (out + dp[i]) % mod; cout << out << endl; return 0; }