牛客寒假集训营第二场I牛牛的“质因数”

前言

昨天是用分段打表过的,看了题解发现可以利用埃氏筛法,感觉还是有一定思维量的。

题目链接

题目链接

题解

在埃氏筛法中,每个合数都有一个质数以及他的倍数筛出,也就是 v i s [ i ∗ j ] = 1 vis[i*j]=1 vis[ij]=1,其中 i i i是质数, i × j i\times j i×j自然是 i i i的倍数。并且这里的 i i i是从小到大枚举的,刚好符合题意。
当枚举到质因子 i i i时,若 j j j中还包含 k k k个质因子 i i i,那我们总共需要将 k + 1 k+1 k+1 i i i连接起来,也就是 d p [ i × j ] = d p [ i × j ] × 10 + i dp[i\times j]=dp[i\times j]\times 10+i dp[i×j]=dp[i×j]×10+i,需要注意的是,这里的 × 10 \times 10 ×10是针对个位数的质因子而言。比如 11 11 11这种不止一位数的因子,我们需要 × 100 \times 100 ×100

代码

/*
 * @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;
}
参考资料
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值