[ 题解 ] [ 数学 ] [ JZOJ5809 ] 数羊

题面

牧羊人 A 和牧羊人 B 总是很无聊,所以他们要玩一个游戏。A 有 a a a 只羊,B 有 b b b 只羊。他们想要知道 a b a^b ab 的因子和是多少。这就很为难两个牧羊人了,由于答案太大,你能不能告诉我答案取模 9901 9901 9901 的数。

Example In #1

2 3

Example Out #1

15

对于 100 100% 100 的数据, 0 ≤ a , b ≤ 50000000 0 \leq a, b \leq 50000000 0a,b50000000

题解

举例:

S = ( 1 + 2 + 4 ) ( 1 + 3 + 9 ) = ( 2 + 4 + 3 + 9 ) + ( 2 × 3 ) + ( 2 × 9 ) + ( 4 × 3 ) + ( 4 × 9 ) = 7 × 13 = 91 \begin{aligned} S &= (1 + 2 + 4)(1 + 3 + 9)\\ &= (2 + 4 + 3 + 9) + (2\times3) + (2\times9) + (4\times3) + (4\times9)\\ &= 7\times13 = 91 \end{aligned} S=(1+2+4)(1+3+9)=(2+4+3+9)+(2×3)+(2×9)+(4×3)+(4×9)=7×13=91

可以看出 S S S 即为 2 3 × 3 2 = 72 2^3\times3^2 = 72 23×32=72 的因数和。
推广到一般:

S = ( 1 + p 1 1 b + p 1 2 b + ⋯ + p 1 k 1 b ) × ⋯ × ( 1 + p m 1 b + p m 2 b + ⋯ + p m k m b ) \begin{aligned} S = (1 + p_1^{1b} + p_1^{2b} + \dots + p_1^{k_1b}) \times \dots \times(1 + p_m^{1b} + p_m^{2b} + \dots + p_m^{k_mb}) \end{aligned} S=(1+p11b+p12b++p1k1b)××(1+pm1b+pm2b++pmkmb)

等比数列求和公式:

S n = a 1 × ( 1 − q n ) 1 − q = a 1 − a n q 1 − q = a n q − a 1 1 − q S_n = \frac{a_1 \times (1 - q^n)}{1 - q} = \frac{a_1 - a_nq}{1 - q} = \frac{a_nq - a_1}{1 - q} Sn=1qa1×(1qn)=1qa1anq=1qanqa1

n n n 为项数, S n S_n Sn 为和, q q q 为公比, a 1 a_1 a1 为首项, a n a_n an 为末项。
此题中:

n = m ( m 为 质 因 数 个 数 ) q = p i a 1 = 1 a n = p i k i b \begin{aligned} &n = m (m 为质因数个数)\\ &q = p_i\\ &a_1 = 1\\ &a_n = p_i^{k_ib} \end{aligned} n=m(m)q=pia1=1an=pikib

代入式中,可见:

S = ∏ i = 1 m p i k i b + 1 − 1 p i − 1 \begin{aligned} S &= \prod_{i = 1}^{m} \frac{p_i ^ {k_ib + 1} - 1}{p_i - 1} \end{aligned} S=i=1mpi1pikib+11

其中,除法取模用费马小定理求乘法逆元。

S = ∏ i = 1 m ( p i k i b + 1 − 1 ) × ( p i − 1 ) ( m o d − 2 ) \begin{aligned} S &= \prod_{i = 1}^{m} (p_i ^ {k_ib + 1} - 1) \times (p_i - 1) ^ {(mod - 2)} \end{aligned} S=i=1m(pikib+11)×(pi1)(mod2)

#include <iostream>
#include <utility>
#include <vector>
#include <cmath>

const int MOD = 9901;
using i64 = long long;

i64 q_pow(i64 a, int b)
{
    i64 res = 1;
    while (b > 0)
    {
        if (b % 2 == 1)
            res = res * a % MOD;
        a = a * a % MOD;
        b /= 2;
    }

    return res;
}

bool is_prime(int n)
{
    for (int i = 2; i <= std::sqrt(n); i++)
        if (n % i == 0)
            return false;
    return true;
}

int main()
{
    int a, b;
    std::cin >> a >> b;

    std::vector<std::pair<int, int>> fac;
    for (int i = 2; i <= std::sqrt(a); i++)
    {
        if (is_prime(i) && a % i == 0)
        {
            fac.emplace_back(i, 0);
            while (a % i == 0)
            {
                a /= i;
                fac.back().second++;
            }
            fac.back().second *= b;
        }
    }
    if (a != 1)
        fac.emplace_back(a, b);

    i64 ans = 1;
    for (auto f : fac)
    {
        i64 res = (q_pow(f.first, f.second + 1) - 1) % MOD;
        res = res * q_pow(f.first - 1, MOD - 2) % MOD;
        ans = ans * res % MOD;
    }

    std::cout << ans;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值