Sumdiv POJ - 1845
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sumdiv POJ - 1845相关的知识,希望对你有一定的参考价值。
题意:
求 A B A^B AB的所有约数之和mod 9901(1<=A,B<=5e7)
题解:
我们先将A分解质因子,表示为:
p
1
c
1
∗
p
2
c
2
∗
.
.
.
.
.
.
∗
p
n
c
n
p_{1}^{c_{1}}*p_{2}^{c_{2}}*......*p_{n}^{c_{n}}
p1c1∗p2c2∗......∗pncn
约数之和我们是有公式的:
A的约数和是:
(
1
+
p
1
+
p
1
2
+
.
.
.
.
+
p
1
c
1
)
∗
.
.
.
.
∗
(
1
+
p
n
+
p
n
2
+
.
.
.
.
+
p
n
c
n
)
(1+p_{1}+p_{1}^2+....+p_{1}^{c_{1}})*....*(1+p_{n}+p_{n}^2+....+p_{n}^{c_{n}})
(1+p1+p12+....+p1c1)∗....∗(1+pn+pn2+....+pncn)
A
B
A^B
AB的所有约数之和为:
(
1
+
p
1
+
p
1
2
+
.
.
.
.
+
p
1
B
∗
c
1
)
∗
.
.
.
.
∗
(
1
+
p
n
+
p
n
2
+
.
.
.
.
+
p
n
B
∗
c
n
)
(1+p_{1}+p_{1}^2+....+p_{1}^{B*c_{1}})*....*(1+p_{n}+p_{n}^2+....+p_{n}^{B*c_{n}})
(1+p1+p12+....+p1B∗c1)∗....∗(1+pn+pn2+....+pnB∗cn)
不难发现,每一项都是一个等比序列,我们用等比序列求和,
(
1
+
p
1
+
p
1
2
+
.
.
.
.
+
p
1
B
∗
c
1
)
=
(
p
1
B
∗
c
1
+
1
−
1
)
/
(
p
1
−
1
)
(1+p_{1}+p_{1}^2+....+p_{1}^{B*c_{1}})=(p_{1}^{B*c_{1}+1}-1)/(p_{1}-1)
(1+p1+p12+....+p1B∗c1)=(p1B∗c1+1−1)/(p1−1)
对于分子分母我们分开求,用快速幂求即可,分母逆元
但是这样并没有结束,什么时候b的逆元是
b
p
−
2
b^{p-2}
bp−2,当p是质数且b与m互质时,本题中9901是质数,但是
p
1
−
1
p_{1}-1
p1−1有可能是9901的倍数,此时乘法逆元就不存在。这种情况特判,此时
(
1
+
p
1
+
p
1
2
+
.
.
.
.
+
p
1
B
∗
c
1
)
≡
1
+
1
+
1
2
+
.
.
.
+
1
B
∗
c
1
≡
B
∗
c
1
+
1
(
m
o
d
9901
)
(1+p_{1}+p_{1}^2+....+p_{1}^{B*c_{1}})\\equiv 1+1+1^2+...+1^{B*c_{1}}\\equiv B*c_{1}+1(\\bmod 9901)
(1+p1+p12+....+p1B∗c1)≡1+1+12+...+1B∗c1≡B∗c1+1(mod9901)
代码:
// Problem: Sumdiv
// Contest: Virtual Judge - POJ
// URL: https://vjudge.net/problem/POJ-1845
// Memory Limit: 30 MB
// Time Limit: 1000 ms
// Data:2021-08-26 14:17:14
// By Jozky
#include <cmath>
#include <cstdio>
#include <ctime>
#include <iostream>
// #include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
x= 0;
char c= getchar();
bool flag= 0;
while (c < '0' || c > '9')
flag|= (c == '-'), c= getchar();
while (c >= '0' && c <= '9')
x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
if (flag)
x= -x;
read(Ar...);
}
template <typename T> inline void write(T x)
{
if (x < 0) {
x= ~(x - 1);
putchar('-');
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef LOCAL
startTime= clock();
freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{
#ifdef LOCAL
endTime= clock();
printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) 以上是关于Sumdiv POJ - 1845的主要内容,如果未能解决你的问题,请参考以下文章