数羊
作者:互联网
题目大意
给定两个正整数 \(a\) 和 \(b\),试求出 \(a^b\) 的因子和。
解题思路
本题钥匙:因子和公式和等比数列求和公式。
现有一数 \(x\)。
先将 \(x\) 质因数分解,即 \(x=a_1^{f_1}+a_2^{f_2}+a_3*{f_3}+ \dots + a_n^{f_n}\)。
则 \(x\) 的因子和即为 \(\prod_{k=1}^{n}\sum_{i=0}^{f_k}a_k^{i}\)。
那么 \(x^y\) 的质因数分解即是 \(a\) 不变,指数乘上 \(y\)。
但是,现在,需要快速求 \(\forall k\in\mathbb{Z},1\le k\le n \sum_{i=0}^{f_k}a_k^{i}\) 这一部分。
设 \(S = \sum_{i=0}^{f_k}a_k^{i}\),则 \(a_kS=\sum_{i=1}^{f_k+1}a_k^{i}\),这一式减去上一式的 \((a_k-1)S=a_k^{f_k+1}-1\),则 \(S=\frac{a_k^{f_k+1} - 1}{a_k-1}\)。
其实是,一样的。
注意,模意义下的除法需要用到逆元。
考场上数组开大 MLE
了,惨丢 \(100pts\),啊!。
AC CODE
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 9901;
int a, b;
int ans = 1;
int k, q[2000005], p[2000005];
int qpow(int x, int y)
{
int ans = 1ll;
while(y)
{
if(y & 1)
{
ans = ans * x % mod;
}
x = x * x % mod;
y /= 2;
}
return ans % mod;
}
signed main()
{
scanf("%lld%lld", &a, &b);
int kk = a;
for(register int i = 2; i * i <= a; ++i)
{
if(kk % i == 0)
{
q[++k] = 1;
p[k] = i;
kk /= i;
}
while(kk % i == 0)
{
q[k]++;
kk /= i;
}
}
if(kk != 1)
{
p[++k] = kk;
q[k] = 1;
}
for(int i = 1; i <= k; ++i)
q[i] *= b;
for(register int i = 1; i <= k; ++i)
{
int x = 1ll * (qpow(p[i], q[i] + 1) - 1) * qpow(p[i] - 1, mod - 2) % mod;
ans = ans * x % mod;
}
printf("%lld\n", ans % mod);
return 0;
}
标签:因数分解,int,sum,因子,ans,数羊,mod 来源: https://www.cnblogs.com/orzz/p/15368497.html