首页 > 其他 > 详细

POJ1845 Sumdiv【因数之和】

时间:2015-03-24 23:00:44      阅读:315      评论:0      收藏:0      [点我收藏+]

题目链接:

http://poj.org/problem?id=1845


题目大意:

对于两个自然数A和B,令s = A^B所有约数和,计算s%9901的结果是多少


思路:

小優的博客对这道题写的非常好,参考博文:http://blog.csdn.net/lyy289065406/article/details/6648539

对A进行素因子分解,A = p1^k1 * p2^k2 * … * pm^km,

则A^B = p1^(k1*B) * p2^(k2*B) * … *pm^(km*B)。

利用乘性函数的性质:

所偶因子和为 s = (1 + p1 + p1^2 + … + p1^(k1*B) ) * (1 + p2 + p2^2 + … + p2^(k2*B)) * … *

                           (1 + pm + pm^2 + … + pm^(km*B))

根据等比数列求和公式可得:s = ( 1+p1^(k1*B+1) )/(p1-1) * (1+p2^(k2*B+1) )/(p2-1) * … * 

  ( 1+pm^(km*B+1) )/(pm-1)

等比数列用二分法来求(这居然都能二分。。。),p^n用整数快速幂来做。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL __int64
using namespace std;

LL Power(LL p,LL n)
{
    LL ret = 1;
    while(n > 0)
    {
        if(n&1)
            ret = ret * p % 9901;
        p = p * p % 9901;
        n >>= 1;
    }
    return ret;
}

LL Sum(LL p,LL n)
{
    if(n == 0)
        return 1;

    if(n&1)
        return (Sum(p,n/2)*(1+Power(p,n/2+1)))%9901;
    else
        return (Sum(p,n/2-1)*(1+Power(p,n/2+1)) + Power(p,n/2))%9901;

}

LL P[10000],M[10000];
int main()
{
    int A,B;
    while(cin >> A >> B)
    {
        int ct = 0;
        memset(M,0,sizeof(M));
/*
        for(int i = 2; i<= A; ++i)
        {
            if(A % i == 0)
            {
                P[ct] = i;
                while(A % i == 0)
                {
                    M[ct]++;
                    A /= i;
                }
                ct++;
            }
        }
*/

        for(int i = 2; i*i <= A; )
        {
            if(A % i == 0)
            {
                P[ct] = i;
                while(A % i == 0)
                {
                    M[ct]++;
                    A /= i;
                }
                ct++;
            }
            if(i == 2)
                i++;
            else
                i += 2;
        }

        if(A != 1)
        {
            P[ct] = A;
            M[ct++] = 1;
        }

        LL ans = 1;
        for(int i = 0; i < ct; ++i)
            ans = ans*(Sum(P[i],M[i]*B)%9901)%9901;
        cout << ans << endl;
    }

    return 0;
}




POJ1845 Sumdiv【因数之和】

原文:http://blog.csdn.net/lianai911/article/details/44600437

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!