zoukankan      html  css  js  c++  java
  • AcWing 97.约数之和

    假设现在有两个自然数A和B,S是AB的所有约数之和。

    请你求出S mod 9901的值是多少。

    输入格式

    在一行中输入用空格隔开的两个整数A和B。

    输出格式

    输出一个整数,代表S mod 9901的值。

    数据范围

    0A,B5×107

    输入样例:

    输出样例:

    注意: A和B不会同时为0。

    【思路】:这是个数学题啊,一开始我的想法是唯一分解出最小的,然后标记存在几次方,然后暴力枚举

         这样是铁定超时的,那么我们要怎么实现这个题目呢?其实是因为我缺乏数学知识,那么我们

         假设唯一分解后的因子集合为{a, b, c} ^ b(这个代表b次方),b == 1;

         那么约数的和sum = 1 + a + b + c + a * b + a * c + b * c + a * b * c

         可以看出sum = (1 + a) * (1 + b) * (1 + c)

         推广后可得sum = (1 + p1 + p1 ^ 2 + ....... + p1 ^ c1) * ...* (1 + pm + .... + pm ^ cm)这里指的是

         n方

         可得这就是一个等比数列求和

         Sn = (1 - q ^ n) / (1 - q)

         那么涉及两种做法

         就是等比数列的答案如何求?

         1,使用分治递归的想法去求解

          当n是偶数的时候,sum(p, c) = 1 + p + p ^ 2 + p ^ 3 + ..... + p ^ n

          举个例子

          1 + p + p2 + p3 + p4 + p5 + p6 + p7 + p8

          (1 + p + p2 + p3) + (p4 + p5 + p6 + p7) + p8

          sum(p, c/2) + p(c / 2)sum(p, c/2) + pc

          (1 + p(c / 2))sum(p, c / 2) + pc

          当n是奇数的时候, 

          举个例子

          1 + p + p2 + p3 + p4 + p5

          (1 + p + p2) + (p3 + p4 + p5)

          (1 + p + p2) + p3(1 + p + p2)

          (1 + p(c + 1 / 2))  * sum(p, c - 1 / 2)

          2, 

    因为求和所以肯定是符合的

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MOD = 9901;
    typedef long long ll;
    /**
     等比数列求和公式:
     (- q ^ n + 1) / (1 - q)
     quick_pow
     质因数分解 + 唯一分解 + 约数求和
     
     **/
    ll quick_pow(ll a, ll b)
    {
        ll ans = 1;
        a %= MOD;
        while(b)
        {
            if(b & 1)
            {
                ans = ans % MOD * a;
            }
            a = a % MOD * a % MOD;
            b >>= 1;
        }
        return ans;
    }
    ll sum(ll p, ll c)
    {
        if (c == 0)
            return 1;
        if(c & 1)
            return ((1 + quick_pow(p,(c + 1) >> 1)) * sum(p,(c - 1) >> 1)) % MOD;
        else
            return ((1 + quick_pow(p,c >> 1)) * sum(p,(c >> 1) - 1) + quick_pow(p,c)) % MOD;
    }
    int a, b;
    int main()
    {
        scanf("%d%d", &a, &b);
        ll sj = a;
        ll ans = 1;
        for(ll i = 2; i * i <= a + 1; i ++)
        {
            ll s = 0;
            while(a % i == 0)
            {
                s ++;
                a /= i;
            }
            //printf("%lld %lld
    ", i, s);
            ans = ans * sum(i, s * b) % MOD;
            //printf("ans = %lld
    ", ans);
        }
        if(a > 1)
            ans = ans * sum(a, b) % MOD;
        if(a == 0)
            printf("0
    ");
        else
        {
            printf("%lld
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    阿里云服务器配置
    linux 环境变量问题
    docker 常用操作
    docker 安装的nginx 的默认配置
    camera开发相关
    Ubuntu下使用Git
    Java web项目实现多附件上传
    Java web项目实现上传图片及时预览
    SQL Server游标【转】
    SQL Server游标的使用【转】
  • 原文地址:https://www.cnblogs.com/qq136155330/p/10418810.html
Copyright © 2011-2022 走看看