Loj 10211 sumdiv

题目描述

求 A^B 的所有约数之和 mo9901。

首先,我们要求出A的约数之和。

就是把A分解质因数,成为:a1^k1*a2^k2*a3^k2....

然后约数和就是(a1^0+a1^1+a1^2+....)*(a2^0+a2^1+....)*.......

那么A的B次方就是每一位都乘以一个B

然后对于每一个ai,都是一个等比数列求和。

然后求和公式需要用到除法,需要逆元。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <queue>
#define in(a) a=read()
#define MAXN 100010
#define REP(i,k,n)  for(long long i=k;i<=n;i++)
using namespace std;
inline long long read(){
    long long x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            f=-1;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return x*f;
}
long long pr[100010],ti[10010];
long long ind=0;
long long mod=9901;
inline void divide(long long n){
    for(long long i=2;i*i<=n;i++)
        if(n%i==0){
            pr[++ind]=i;
            while(n%i==0){
                n=n/i;
                ti[ind]++;
            }
        }
    if(n>1){
        pr[++ind]=n;
        ti[ind]=1;
    }
    return ;
}
inline long long qpow(long long a,long long b){
    long long ans=1;
    while(b){
        if(b%2)  ans=(ans*a)%mod;
        b/=2;
        a=(a*a)%mod;
    }
    return ans;
}
int main(){
    long long a,b;
    long long ans=1;
    in(a),in(b);
    divide(a);
    REP(i,1,ind){
        if(pr[i]-1%mod==0)
            ans=ans*(ti[i]*b)%mod;
        long long den,dor;
        den=qpow(pr[i],b*ti[i]+1)-1;
        dor=qpow(pr[i]-1,mod-2);
        ans=(ans*(den*dor)%mod)%mod;
    }
    cout<<ans;
    return 0;
}

 

posted @ 2019-03-16 13:22  Dijkstra·Liu  阅读(227)  评论(0编辑  收藏  举报