您的位置:首页 > 其它

[POJ1845]Sumdiv

2015-08-17 21:42 337 查看
这道题考察了三个数论的公式定理:

整数唯一分解定理:a=(p1^k1)*(p2^k2)**...*(pn^kn) (p(i)为质数)

因数和公式 (已知a=(p1^k1)*(p2^k2)**...*(pn^kn)),则A的所有因子之和为:sum = (1+p1+p1^2+...p1^k1)*(1+p2+p2^2+...p2^k2)*...*(1+pn+pn^2+...pn^kn)

同余模公式:

(a+b)%m=(a%m+b%m)%m

(a*b)%m=(a%m*b%m)%m

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long long LL;
const int mod = 9901;
vector<LL> p;
vector<LL> k;
LL n, a, b;

//快速幂
LL quickmul(LL x, LL n) {
LL ans = 1;
LL t = x;
while(n) {
if(n & 1) {
ans = (ans * t) % mod;
}
t = t * t % mod;
n >>= 1;
}
return ans;
}

//分解质因数
void factor(LL n) {
p.clear();
k.clear();
int nn = (int)sqrt(n*1.0);
for(int i = 2; i <= nn; i+=2) {
if(n % i == 0) {    //分解n,使n变为p1^k1*p2^k2+...pn^kn
p.push_back(i);
k.push_back(0);
while(n % i == 0) {
k.back()++;
n = n / i;
}
}
if(i == 2) {
i--;
}
if(n == 1){
break;
}
}
if(n != 1) {    //特判质数
p.push_back(n);
k.push_back(1);
}
}

//同余模公式
//(a+b)%m=(a%m+b%m)%m
//(a*b)%m=(a%m*b%m)%m
//二分求1+pi+pi^2+...+pi^n的和
LL modu(LL x,LL y) {
if(y == 0) {
return 1;
}
if(y % 2 == 0) {
return (((modu(x,y/2-1)%mod)*((1+quickmul(x,y/2+1))%mod))%mod+quickmul(x,y/2)%mod)%mod;
}
if(y % 2 != 0) {
return (modu(x,y/2)%mod)*((1+quickmul(x,y/2+1))%mod)%mod;
}
}

void solve() {
factor(a);  //分解a,使a = p1^k1*p2^k2+...pn^kn
for(int i = 0; i < k.size(); i++) {
k[i] = k[i] * b; //所以a^b = p1^(k1*b)*p2^(k2*b)...pn^(kn*b)
}
LL sum = 1;
for(int i = 0; i < k.size(); i++) {
sum = sum * modu(p[i], k[i]) % mod;
}
printf("%I64d\n", sum);
}

int main() {
while(~scanf("%d %d", &a, &b)) {
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: