洛谷 P2715 约数和

给出a和b求a^b的约数和。

题目描述

输入输出格式

输入格式:

 

一行两个数a,b。

 

输出格式:

 

一个数表示结果对 9901 的模。

 

输入输出样例

输入样例#1:
2 3
输出样例#1:
15

说明

对于 30%的数据,a,b≤ 10 对于 100%的数据,0 ≤ a,b ≤ 50 000 000

 

早上听大爷讲完数论马上回来补了一道

这题呢 我们首先可以吧a质因数分解 表示为p1^c1 × p2^c2 ×……× pn^cn

那么a^b就可以表示为p1^(c1*B) × p2^(c2*B) ×……× pn^(cn*B)

A^B的约数表示为p1^k1 × p2^k2 ×……× pn^kn,其中0<=ki<=ci*B

那么所有的约数和就是(1+p1+p1^2+……+p1^(c1*B)) × (1+p2+p2^2+……+p2^(c2*B)) ×……× (1+pn+pn^2+……+pn^(cn*B))

这个拿乘法定律什么的搞一下就可以得到了哇

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=9901;
LL read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
LL n,m,ans=1;
LL sum[255],h[255],cnt;
LL qmod(LL a,LL b){
    LL ans=1;
    while(b){
        if(b&1) ans=ans*a%mod;
        b>>=1; a=a*a%mod;
    }
    return ans;
}
void prepare(){
    LL v=n;
    for(int i=2;i<=v;i++)if(n%i==0){
        sum[++cnt]=i; 
        h[cnt]++;
        n/=i;
        while(n%i==0) h[cnt]++,n/=i;
        h[cnt]*=m;
        if(!n) return ;
    }
}
int main()
{
    n=read(); m=read(); prepare();
    //for(int i=1;i<=cnt;i++) printf("[%lld %lld]\n",sum[i],h[i]);
    for(int i=1;i<=cnt;i++){
        LL q=qmod(sum[i]-1,mod-2),p=qmod(sum[i],h[i]+1)-1;
        ans=ans*p%mod*q%mod;
    }printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2017-08-01 13:47  友人Aqwq  阅读(158)  评论(0编辑  收藏  举报