Codeforces Round #330 (Div. 2) B. Pasha and Phone · 数学

本文探讨了一道关于数论的题目,通过分析长度为n的数被分成若干块的组合方式,研究每一块既能被特定数值整除又不以特定数值开头的数的种类。文章提供了详细的解题思路与C++代码实现。

题解

题意:长度为 nnn 的数被分成 kn\frac{k}{n}nk 块,要求每一块 iii 的都能被 aia_iai 整除,且不能是以 bib_ibi 开头,问满足要求的数有多少种

1∼x1\sim x1x 之中,能被 ppp 整除的数有 ⌊xp⌋\left\lfloor\frac{x}{p}\right\rfloorpx 个,如果有0,答案 +1

每一块 kkk 位数,能被 aaa 整除的数总共有 10k−1a+1\frac{10^k-1}{a} +1a10k1+1

能被 aaa 整除的、又是以 bbb 开头的数总共有 b×10k−1−1a−(b−1)×10k−1−1a\frac{b\times 10^{k-1}-1}{a}-\frac{(b-1)\times 10^{k-1}-1}{a}ab×10k11a(b1)×10k11


在这里插入图片描述


代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int a[N], b[N];
int n, k;
int p[20];

int main() {
    ios::sync_with_stdio(0);

    p[0] = 1;
    for (int i = 1; i <= 9; ++i) {
        p[i] = p[i - 1] * 10;
    }

    cin >> n >> k;
    int block = n / k;
    for (int i = 1; i <= block; ++i) {
        cin >> a[i];
    }
    for (int i = 1; i <= block; ++i) {
        cin >> b[i];
    }

    ll res = 1;
    for (int i = 1; i <= block; ++i) {
        ll tmp1 = (p[k] - 1) / a[i] + 1;
        ll tmp2 = (p[k - 1] * (b[i] + 1) - 1) / a[i] + 1;
        ll tmp3 = (p[k - 1] * b[i] - 1) / a[i] + 1;
        if (!b[i]) tmp3 = 0; //没有这一块了

        res *= tmp1 - tmp2 + tmp3;
        res %= mod;
    }
    cout << res << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值