poj1845(二分快速求等比数列模M和)

                                         Sumdiv
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 17039   Accepted: 4280

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

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define MOD 9901

typedef long long ll;
//a^b%mod 快速幂
long long Quk_Mul(long long a,long long b,long long mod)
{
    long long qsum=1;
    while(b)
    {
        if(b&1) qsum=(qsum*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return qsum;
}//二分计算1+a+a^2+...+a^b

long long Bin_Find(int a,long long b)
{
    if(b==0) return 1;
    if(b%2==0)
    {
        return ( Bin_Find(a, b/2-1)+Bin_Find(a, b/2-1)*Quk_Mul(a, b/2+1, MOD)+Quk_Mul(a, b/2, MOD) )%MOD;
    }
    else
    {
        return ( Bin_Find(a, b/2)+Quk_Mul(a, b/2+1, MOD)*Bin_Find(a, b/2) )%MOD;
    }
}

long long GetDivsorSum(int x,int b)
{
    long long sum=1;
    for(int i=2;i*i<=x;i++)
    {
        long long tmp=0;
        if(x%i == 0)
        {
            while(x%i==0)
            {
                x/=i;
                tmp++;
            }
            //假设
            tmp *= b;
            sum *= Bin_Find(i,tmp);
            sum%=MOD;
        }
    }
    
    if(x>1)//在这里x可能等于 9901
    {
        long long tmp=1;
        tmp *= b;
        int i=x;
        sum *= Bin_Find(i, tmp);
        sum%=MOD;
    }
    return sum;
}

int main(int argc, const char * argv[]) {
    int a,b;
    // for(int i=2;i<9901;i++)
    //    if(9901%i==0) printf("%d\n",i);
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        if(a==0)
        {
            printf("0\n");
        }
        else if(b==0)
            printf("1\n");
        else
            cout<<(GetDivsorSum(a,b)%MOD+MOD)%MOD<<endl;
        /*
         long long tmp=1;
         long long ans=0;
         for(int i=0;i<b;i++) tmp*=a;
         for(int j=1;j<=tmp;j++)
         {
         if(tmp%j==0) ans=ans+j;
         ans%=MOD;
         }
         cout<<ans<<endl;
         */
    }
    return 0;
}

//求一个数的因子和。因为求逆元不是很方便,所以采用二分求等比数列和

posted @ 2015-12-09 22:53  chenhuan001  阅读(363)  评论(0编辑  收藏  举报