POJ
来源:互联网 发布:linux sd卡自动挂载 编辑:程序博客网 时间:2024/06/07 10:03
题目链接:https://vjudge.net/problem/POJ-1845
题目大意:求A^B的所有因数和
解题思路:由约数和定理可以知道,A可以分解成p1^a1*p2^a2*……pk^ak,那么A^B为p1^(a1*B)*p2^(a2*B)……pk^(ak*B),那么因数和为(1+p1+p1^2+……+p1^(a1*b))……*(1+pk+pk^2+……+pk^(ak*b))
解法一:
对于1+p+p^2+……+p^n,当n为奇数时,等价于(1+p+…..p^(n/2))(p^(n/2+1)+1),当n为偶数时,等价于(1+p+…..p^(n/2))(p^(n/2+1)+1)-p^(n+1),所以可以用递归求解
AC代码:
#include<cstdio>#include<map>using namespace std;typedef long long LL;const int Mod = 9901;const int MAXN = 10000;bool vis[MAXN];int prime[MAXN], tot;map<int, int> mp;void toInit(){ tot = 0; for (int i = 2;i < MAXN;i++) { if (!vis[i]) prime[tot++] = i; for (int j = 0;j < tot&&prime[j] * i < MAXN;j++) { vis[prime[j] * i] = 1; if (i%prime[j] == 0) break; } }}void toDivide(int n){ for (int i = 0;i<tot&&prime[i] <= n;i++) { while (n%prime[i] == 0) mp[prime[i]]++, n /= prime[i]; } if (n > 1) mp[n]++;}LL quickMod(LL a, LL b){ a %= Mod; LL ans = 1; while (b) { if (b & 1) ans = ans*a%Mod; a = a*a%Mod; b >>= 1; } return ans;}LL toDfs(LL p,LL n){ if (n == 0) return 1; LL ans=toDfs(p, n / 2)*(quickMod(p, n / 2 + 1) + 1) % Mod; if (n % 2) return ans; return ((ans - quickMod(p, n + 1)) % Mod + Mod) % Mod;}int main(){ toInit(); int a, b;scanf("%d%d", &a, &b); toDivide(a); LL ans = 1; for (map<int, int>::iterator it = mp.begin();it != mp.end();it++) ans *= toDfs(it->first, (it->second)*b), ans %= Mod; printf("%I64d\n", ans); return 0;}
解法二:
对于1+p+p^2+……+p^n,可以直接用等比数列求和公式得(p^(n+1)-1)/(p-1),对于形如(a/b)%m且b|a,这里介绍当b与m不互为素数时的处理方法,(a/b)%m=(a%(b*m))/b,快速幂乘积时会爆longlong,所以用快速乘处理
AC代码:
#include<cstdio>#include<map>using namespace std;typedef long long LL;const int Mod = 9901;const int MAXN = 10000;bool vis[MAXN];int prime[MAXN], tot;map<int, int> mp;void toInit(){ tot = 0; for (int i = 2;i < MAXN;i++) { if (!vis[i]) prime[tot++] = i; for (int j = 0;j < tot&&prime[j] * i < MAXN;j++) { vis[prime[j] * i] = 1; if (i%prime[j] == 0) break; } }}void toDivide(int n){ for (int i = 0;i<tot&&prime[i] <= n;i++) { while (n%prime[i] == 0) mp[prime[i]]++, n /= prime[i]; } if (n > 1) mp[n]++;}LL quickMul(LL a, LL b, LL m){ a %= m; LL ans = 0; while (b) { if (b & 1) ans = (ans + a) % m; a = (a + a) % m; b >>= 1; } return ans;}LL quickPow(LL a, LL b, LL m){ a %= m; LL ans = 1; while (b) { if (b & 1) ans = quickMul(ans, a, m); a = quickMul(a, a, m); b >>= 1; } return ans;}int main(){ toInit(); LL a, b;scanf("%I64d%I64d", &a, &b); toDivide(a); LL ans = 1; for (map<int, int>::iterator it = mp.begin();it != mp.end();it++) { LL down = it->first - 1; LL M = down*Mod; LL up = (quickPow(it->first, it->second*b + 1, M) - 1 + M) % M; ans *= (up / down); ans %= Mod; } printf("%I64d\n", ans); return 0;}
阅读全文
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- 第十一篇:C代码调用Java代码之项目实战
- HDU 4002 数论
- springboot学习笔记五
- BDKR_hashz字符串(自己的理解)
- hdu 2680 Choose the best route【dijstra+反向建图】
- POJ
- 58面试整理
- poj3026 Borg Maze
- 杭电acm2040:亲和数(两整数真约数和互等)
- 6.递归调用 函数 (-斐波那契数列)
- 在Ubuntu 12.04 64bit搭建Android编译环境后,重启卡住在Ubuntu logo,进不了图形界面
- python爬虫之快速构造标准格式headers
- 得到文件夹中的文件列表的方法
- Codeforces 346B