等比数列求和 (快速幂 + 逆元)
  anLrwkgbyYZS 2023年12月30日 16 0


     求一个等比数例之和, 并让他对一个数取模。

     用到等比数列求和公式, 快速幂, 逆元。

     不会证明, 下面给出代码。

#include <stdio.h>
#include <string.h>
#include <math.h>
typedef  long long ll;
ll multi(ll a,ll b,ll m)  // 二分乘法
{
    ll ans = 0;
    a %= m;
    while(b)
    {
        if(b & 1)
        {
            ans = (ans + a) % m;
            b--;
        }
        b >>= 1;
        a = (a + a) % m;
    }
    return ans;
}
ll quick_mod(ll a,ll b,ll mod)
{
    ll res = 1;
    while(b)
    {
        if(b % 2 == 1)
            res = multi(res, a, mod);
        // 二分乘法 不然会数据溢出
        b >>= 1;
        a = multi(a, a, mod);
        // 二分乘法 不然会数据溢出
    }
    return res;
}
int main()
{
    ll a, b, mod=9901;
    scanf("%I64d %I64d",&a, &b);
    // 首项为 1 , 公比为 a,长度 为 b 的等比数例求和
    printf("%I64d\n",((quick_mod(a,b,mod*(a-1)) - 1) / (a-1)));
    return 0;
}

Sumdiv

 

 

Time Limit: 1000MS

 

Memory Limit: 30000K

Total Submissions: 23623

 

Accepted: 5876

Description

Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).

Input

The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.

Output

The only line of the output will contain S modulo 9901.

Sample Input

2 3

Sample Output

15

Hint

2^3 = 8. 
The natural divisors of 8 are: 1,2,4,8. Their sum is 15. 

15 modulo 9901 is 15 (that should be output). 

 

思路: 举一个例子: 36, 1。  

          先把 36 分解成质因数, 2, 2,3, 3。

            ans = 1 ,  2,   2*2,   1*(3 +  3*3),   2 * (3 + 3*3)  ,  2*2 *(3 * 3). 之和。

#include <stdio.h>
#include <string.h>
#include <math.h>
typedef long long ll;
int p[10005];
void prime() // 打一个素数表
{
    p[1] = 2;
    int cnt = 1;
    for(int i=3; i<=10000; i+=2)
    {
        int flag = true;
        for(int j=2; j*j<=i; j++)
        {
            if(i%j == 0)
            {
                flag = false;
                break;
            }
        }
        if(flag)
            p[++cnt] = i;
    }
}
ll multi(ll a,ll b,ll m)  // 二分乘法
{
    ll ans = 0;
    a %= m;
    while(b)
    {
        if(b & 1)
        {
            ans = (ans + a) % m;
            b--;
        }
        b >>= 1;
        a = (a + a) % m;
    }
    return ans;
}
ll quick_mod(ll a,ll b,ll mod) // 快速幂
{
    ll res = 1;
    while(b)
    {
        if(b % 2 == 1)
            res = multi(res, a, mod);

        b >>= 1;
        a = multi(a, a, mod);

    }
    return res;
}
int main()
{
    ll a, b, mod=9901;
    scanf("%I64d %I64d",&a, &b);

    if(a == 1)
    {
        printf("1\n");
        return 0;
    }

    prime();
    ll ans = 1;
    int num = 0;

    for(int i=1; p[i]*p[i]<=a; i++)
    {
        if(a % p[i] == 0) // 寻找每个质因数 和 它的数量 num。
        {
            num=0;
            while(a % p[i] == 0)
            {
                num++;
                a /= p[i];
            }

            ll m =(p[i] - 1) * mod;

            ans *= ((quick_mod(p[i], num*b+1, m) + m - 1) / (p[i]-1)); // 等比数列求和
            //	printf("%lld\n",(quick_mod(p[i], num*b+1, m) + m - 1) / (p[i]-1) % mod);
            ans %= mod;
        }
    }

    ll m = mod * (a - 1);
    if(a > 1)
        printf("%I64d\n",ans * ((quick_mod(a, b+1, m) + m - 1) / (a-1)) % mod);
    else
        printf("%I64d\n",ans % mod);

    return 0;
}

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月30日 0

暂无评论

anLrwkgbyYZS