每日一题 AcWing 97.约数之和

AcWing 97.约数之和

题目:

假设现在有两个自然数 A 和 B,S 是 A^B 的所有约数之和。

请你求出 S mod 9901 的值是多少。

输入格式

在一行中输入用空格隔开的两个整数 A 和 B。

输出格式

输出一个整数,代表 S mod 9901 的值。

数据范围

0≤ A,B ≤ 5×10^7

输入样例:

2 3

输出样例:

15

注意: AA 和 BB 不会同时为 00。

思路:

A = p 1 k 1 ∗ p 2 k 2 ∗ p 3 k 3 ∗ . . . ∗ p n k n A = p1^{k1}*p2^{k2} * p3^{k3}*...*pn^{kn} A=p1k1p2k2p3k3...pnkn

因数的个数: ( k 1 + 1 ) ∗ ( k 2 + 1 ) ∗ ( k 3 + 1 ) ∗ . . . ∗ ( k n + 1 ) (k1+1)*(k2+1)*(k3+1)*...*(kn+1) (k1+1)(k2+1)(k3+1)...(kn+1)

因数和: ( p 1 0 + p 1 1 + . . . + p 1 k 1 ) ∗ ( p 2 0 + p 2 1 + . . . + p 2 k 2 ) ∗ . . . ∗ ( p n 0 + p n 1 + . . . + p n k n ) (p1^0+p1^1+...+p1^{k1})*(p2^0+p2^1+...+p2^{k2})*...*(pn^0+pn^1+...+pn^{kn}) (p10+p11+...+p1k1)(p20+p21+...+p2k2)...(pn0+pn1+...+pnkn)

设置函数 s u m ( p , k ) = ( p 0 + p 1 + . . . + p k ) sum(p,k)=(p^0+p^1+...+p^k) sum(p,k)=(p0+p1+...+pk)

k k k 为奇数:

s u m ( p , k ) = ( p 0 + p 1 + . . . + p k / 2 + p k / 2 + 1 + . . . + p k ) sum(p,k)=(p^0+p^1+...+p^{k/2}+p^{k/2+1}+...+p^k) sum(p,k)=(p0+p1+...+pk/2+pk/2+1+...+pk)

= ( 1 + p k / 2 + 1 ) ∗ ( p 0 + p 1 + . . . + p k / 2 ) =(1 + p^{k/2 + 1})*(p^0 + p^1 + ... + p^k/2) =(1+pk/2+1)(p0+p1+...+pk/2)

= ( 1 + p k / 2 + 1 ) ∗ s u m ( p , k / 2 ) =(1 + p^{k/2 + 1})*sum(p, k/2) =(1+pk/2+1)sum(p,k/2)

k k k 为偶数:

s u m ( p , k ) = 1 + p ∗ ( p 0 + p 1 + . . . + p k − 1 ) sum(p,k)=1 + p * (p^0 + p^1 + ... + p^{k-1}) sum(p,k)=1+p(p0+p1+...+pk1)

= 1 + p ∗ s u m ( p , k − 1 ) =1 + p * sum(p, k - 1) =1+psum(p,k1)

代码:
package 基本算法.递推与递归.约数之和;
import java.util.Scanner;
public class Main {
	public static final int MOD = 9901;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int A = in.nextInt();
		int B = in.nextInt();
		int res = 1;
		for(int i = 2; i <= A; i++) {
			int s = 0;
			while(A % i == 0) {
				s++;
				A /= i;
			}
			if(s != 0) {
				res = res * sum(i, s*B) % MOD;
			}
		}
		if(A == 0) res = 0;
		System.out.println(res);
		
		in.close();
	}
	
	public static int sum(int p, int k) {
		if(k == 0) return 1;
		if(k % 2 == 0) return (p % MOD * sum(p, k-1) + 1) % MOD;
		return (1 + qmi(p, k/2+1)) % MOD * sum(p, k/2)% MOD;
	}
	
	public static int qmi(int p, int k) {
		p %= MOD;
		int res = 1;
		while(k != 0) {
			if((k & 1) != 0) res = res * p % MOD;
			p = p*p % MOD;
			k >>= 1;
		}
		return res;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值