因子和

题目描述

输入两个正整数a和b,求ab的因子和。结果太大,只要输出它对9901的余数。

输入输出格式

输入格式:

仅一行,为两个正整数a和b(0≤a,b≤50000000)。

输出格式:

a^b的因子和对9901的余数。

输入输出样例

输入样例#1

2 3

输出样例#1

15

题解

根据约数和定理: 若

n=i=1k=pa11×pa22×pa33××pakk(pin,ai) n = ∏ i = 1 k = p 1 a 1 × p 2 a 2 × p 3 a 3 × ⋯ × p k a k ( 其 中 p i 为 n 的 质 因 数 , a i 为 正 整 数 )

n n 的所有正约数之和为
f(n)=i=1k(j=0aipj)=(1+p1+p21+p31++pa11)×(1+p2+p22+p32++pa22)××(1+pk+p2k+p3k++pakk f ( n ) = ∏ i = 1 k ( ∑ j = 0 a i p j ) = ( 1 + p 1 + p 1 2 + p 1 3 + ⋯ + p 1 a 1 ) × ( 1 + p 2 + p 2 2 + p 2 3 + ⋯ + p 2 a 2 ) × ⋯ × ( 1 + p k + p k 2 + p k 3 + ⋯ + p k a k

S=1+pk+p2k+p3k++pakk S = 1 + p k + p k 2 + p k 3 + ⋯ + p k a k pkS=pk+p2k+p3k++pakk+pak+1k p k S = p k + p k 2 + p k 3 + ⋯ + p k a k + p k a k + 1
后面的式子减前面的式子得: (pk1)S=pak+1k1 ( p k − 1 ) S = p k a k + 1 − 1

S=pak+1k1pk1 S = p k a k + 1 − 1 p k − 1

最后通过逆元+快速幂计算即可

#include
#define gc getchar
#define ll long long
inline ll read(){ll x = 0; char ch = gc(); bool positive = 1;for (; !isdigit(ch); 
ch = gc()) if (ch == '-')  positive = 0;for (; isdigit(ch); ch = gc())  x = x * 10 
+ ch - '0';return positive ? x : -x;}inline void write(ll a){if(a>=10)write(a/10);
putchar('0'+a%10);}inline void writeln(ll a){if(a<0){a=-a; putchar('-');}write(a);
puts("");}

using namespace std;

const int N = 10000, p = 9901;

ll num[N], cnt[N], tot;

inline ll ksm(ll a, ll b) {
    ll res = 1;
    for(; b; b >>= 1, a = a * a % p)
        if(b & 1)
            res = res * a % p;
    return res;
}

int main() {
    ll x, a, b, y, ans = 1;
    x = read(), y = read();
    for(ll i = 2; i <= x; ++i)
        if(x % i == 0) {
            num[++tot] = i;
            while(x % i == 0) {
                ++cnt[tot];
                x /= i;
            }
            cnt[tot] *= y;
        }
    for(int i = 1; i <= tot; ++i) {
        a = ksm(num[i], cnt[i] + 1) - 1;
        b = ksm(num[i] - 1, p - 2);
        ans = ans * a * b % p;
    }
    writeln((ans + p ) % p);
    return 0;
}

你可能感兴趣的:(因子和)