poj 1845 Sumdiv

将a^b进行素数分解为a1^p1*a2^p2*……ai^pi;

则因子之和为:(1+a1+a1^2+……+a1^p1)*(1+a2+a2^2+……+a2^p2)……(1+ai+ai^2+……+ai^pi)

这样就方便多了,使用二分快速幂可以快速求出结果……

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

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<iomanip>
#include<string>
using namespace std;
int prime[10001],k,f[10001],e[10001];
bool a[10001];
const int M=9901;
void init()
{
    int i,j;
    k=0;
    for(i=2;i<=10000;i++)
    {
        if(!a[i])
        {
            prime[k++]=i;
            for(j=i+i;j<=10000;j+=i)
                a[j]=1;
        }
    }
}
__int64 pow(__int64 n,__int64 t)
{
    __int64 res=1;
    while(t)
    {
        if(t&1)
            res=res*n%9901;
        t>>=1;
        n=n*n%9901;
    }
    return res;
}
__int64 sum(__int64 p,__int64 t)
{
    if(t==0) return 1;
    if(t&1)
        return ((1+pow(p,t/2+1))%M*sum(p,t/2)%M)%M;
    else
      return ((1+pow(p,t/2+1))%M*sum(p,t/2-1)%M+pow(p,t/2)%M)%M;
}
int main()
{
    __int64 a,b,i,j,x,ans;
    init();
    while(scanf("%I64d%I64d",&a,&b)!=EOF)
    {
        ans=1;
        for(i=0;i<k&&a>1;i++)
        {
            if(a%prime[i]==0)
            {
                x=0;
                while(a%prime[i]==0)
                {
                    a/=prime[i];
                    x++;
                }
                ans=(ans*sum(prime[i],x*b))%9901;
            }
        }
        if(a>1) 
        {
            ans=(ans*sum(a,b))%9901;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

 

posted @ 2013-07-15 09:58  _随心所欲_  阅读(242)  评论(0编辑  收藏  举报