其他分享
首页 > 其他分享> > 数羊

数羊

作者:互联网

题目大意

给定两个正整数 \(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