HDU 1452 Happy 2004

本文解析了一道ACM竞赛中的数学题目,通过整数唯一分解定理和约数和公式来计算2004^X的所有正整数因子之和,并对其结果对29取模。介绍了快速幂取模计算及乘法逆元的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在ACM中,数学题很多,数学也是相当重要的。本题就要用到数学知识,真是书到用时方恨少,大家还是多记数学定理和结论吧。

Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).

Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.

Input The input consists of several test cases. Each test case contains a line with the integer X (1 <= X <= 10000000).

A test case of X = 0 indicates the end of input, and should not be processed.
Output For each test case, in a separate line, please output the result of S modulo 29.
Sample Input
1
10000
0
Sample Output
6
10

分析一下,本题求的是2004^x的约数和对29取模,这里我们要计算,约数和,下面介绍两个定理:

①整数唯一分解定理:

一个整数A一定能被分成:A=(P1^K1)*(P2^K2)*(P3^K3).....*(Pn^Kn)的形式。其中Pn为素数。

如2004=(22)*3*167。

那么2004x=(22x)*(3x)*(167x)。

②约数和公式

对于一个已经被分解的整数A=(P1^K1)*(P2^K2)*(P3^K3).....*(Pn^Kn),

有约数和S=(1+P12+P13+.....P1k1)*.....(1+Pn2+Pn3+.....Pnkn)。

(1+P12+P13+.....P1k1)是一个等比数列,化简为(P1k1+1 -1)/(P1-1).

对于2004^X, 只要求出a=pow(2,2*x+1)-1,b=pow(3,x+1)-1,c=pow(167,x+1)-1即可,使用快速幂取模计算。

所以我们要算的是(a*b/2*c/166)%29,那么里面这个除法怎么处理呢,方法就是取乘法逆元,也就是说令e=2*166%29=9,则(a*b/2*c/166)%29=(a*b*c*e)%29。

下面是代码:

#include<cstdio>
#define ll long long
const int mod=29;
ll quickpow(ll a,ll b){
	ll ans=1;
	a=a%mod;
	while(b){
		if(b&1) ans=ans*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ans;
}
int main()
{
	ll x;
	while(~scanf("%lld",&x)&&x){
		ll a=quickpow(2,2*x+1)-1;
		ll b=quickpow(3,x+1)-1;
		ll c=quickpow(167,x+1)-1;
		printf("%lld\n",(a*b*c*9)%mod);
	}
 } 

当然,在网上查的时候看有的兄弟找出了规律做,在下实在佩服,可以参考:点击打开链接

可能有的人不理解上面的除法(a*b/2*c/166)%29=(a*b*c*e)%29取模,其实这也是个推出来的结论,记忆就行了:

(因为这里a、b、c是取模后的结果,所以不能拿他们直接除2*166,但是如果不取模可以除,但是太大了一定会溢出)

当我们要求(a / b) mod p的值,且 a 很大,无法直接求得a / b的值时,我们就要用到乘法逆元。
满足 b * k ≡ 1 (mod p) 的 k 的值就是 b 关于 p 的乘法逆元。

我们可以通过求 b 关于 p 的乘法逆元 k,将 a 乘上 k 再模 p,即 (a * k) mod p。其结果与(a / b) mod p等价

(可以用扩展欧几里得)

在下实力有限,欢迎大家指出错误,谢谢。

转载于:https://www.cnblogs.com/RenoStudio/p/10355195.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值