Sumdiv POJ - 1845

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sumdiv POJ - 1845相关的知识,希望对你有一定的参考价值。

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}} p1c1p2c2......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+....+p1Bc1)....(1+pn+pn2+....+pnBcn)
不难发现,每一项都是一个等比序列,我们用等比序列求和, ( 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+....+p1Bc1)=(p1Bc1+11)/(p11)
对于分子分母我们分开求,用快速幂求即可,分母逆元
但是这样并没有结束,什么时候b的逆元是 b p − 2 b^{p-2} bp2,当p是质数且b与m互质时,本题中9901是质数,但是 p 1 − 1 p_{1}-1 p11有可能是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+....+p1Bc1)1+1+12+...+1Bc1Bc1+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的主要内容,如果未能解决你的问题,请参考以下文章

poj1845 Sumdiv

poj_1845_Sumdiv

POJ1845 Sumdiv [数论,逆元]

POJ1845 Sumdiv

POJ - 1845 G - Sumdiv (唯一分解定理)

POJ 1845 Sumdiv#质因数分解+二分