A^B所有因子和(poj1845 Sumdiv)

题意:
AB 所有因子的和。mod 9901

思路:
把A表示成: piki .
那么所有因子的和就为: (pi1)(pi2)...(pin) ;
AB 就相应让指数变为 B 倍。
然后再用等比数列求和公式。

#include <iostream>
#include <cmath>
#include <stdio.h>
#include <map>
#include <algorithm>
using namespace std;
#define LL long long 
#define MAX 100000
#define MD 9901

void ext_gcd(int a,int b,int &d,int &x,int &y)
{
    if(b==0)
    {
        x=1;y=0;
        d=a;
        return ;
    }
    ext_gcd(b,a%b,d,y,x);
    y-=(a/b)*x;
}

int inv(int n)
{
    int d,x,y;
    ext_gcd(n,MD,d,x,y);
    return (d==1?(x%MD+MD)%MD:-1);
}

LL pow_mod(LL a,LL b, LL mod)
{
    if(!b) return 1;
    if(b==1) return a%mod;
    LL c=pow_mod(a,b/2,mod);
    c=c*c;
    c%=mod;
    if(b%2)
        c*=a;
    return c%mod;
}

LL solve(LL b,LL p,LL k)
{
    LL ans=1;
    if(p%MD==0)
        return 1;
    if(p%MD==1)
    {
        ans*=b*k+1;
        ans%=MD;
    }
    else
    {
        LL temp=pow_mod(p,b*k+1,MD);
        ans=(ans*(temp-1))%MD;
        LL iv=inv(p-1);
        if(iv!=-1)
            ans=(ans*iv)%MD;
        //else cout<<"error";
        ans=(ans%MD+MD)%MD;
    }
    return ans;
}
int prim[10000],k[10000];
int main()
{
    LL a,b;
    LL p,k;
    LL ans;
    //freopen("1.txt","r",stdin);
    while(~scanf("%I64d%I64d",&a,&b))
    {
        int num=0;
        ans=1;
        if(b==0)
        {
            puts("1");
            continue;
        }
        if(!a)
        {
            puts("0");
            continue;
        }
        for (int i=2;i*i<=a;++i)
        {
            p=k=0;
            if(a%i==0)
            {
                p=i;
                a/=i;
                k++;
                while(a%i==0)
                {
                    a/=i;k++;
                }
            }
            ans*=solve(b,p,k);
            ans%=MD;
        }
        if(a!=1)
        {
            ans*=solve(b,a,1);
            ans%=MD;
        }
        ans=(ans%MD+MD)%MD;
        printf("%I64d\n",ans);
    }
}

你可能感兴趣的:(A^B所有因子和(poj1845 Sumdiv))