【竞赛知识ONE】取余问题

本文介绍了在竞赛编程中处理取余问题的重要性,以防数据溢出。文章通过一个案例分析,讲解了两种不同的取模策略:一是对每个加数单独取模再相加,二是对乘积在每次计算后立即取模。这两种方法可以确保计算过程中的中间结果保持在安全范围内。

前言:

在一些竞赛题中,往往要求对最终的数据结果进行取余或者求模运算。但是如果仅仅只是在输出最终结果的时候对某个数取模,那么可能会导致数据溢出等问题,所以在计算过程中也需要对中间数据进行取模操作。

定理:

举例:     

1. 案例一

解题分析:思路并不难理解计算每一个阶乘的大小,然后想加求模即可(只取后六位数据意思就是对1000000取模求余操作),如下所示:

最终结果  ANS  = (1!+ 2!+3!+ ...+n!)% MOD

如果不对上式的中间数据(例如25!或 前 N 项的阶乘和)进行限制的话,会导致数据溢出

因为数据太大了,远超过了 INT 类型可表示的范围

那么如何对中间数据进行操作,需要明白取模的定理,有点类似于分配率等定理

第一种:对每个加数进行取余,然后将每次想加的结果再次取余,即:

最终结果  ANS  =【 (1!% MOD +2!% MOD)% MOD + (3!%MOD)】%MOD

就是这种逻辑,可以保证每一次加法后的结果不超限,但是无法保证阶乘的结果不超限

第二种:原理是(A*B*C)% MOD = 【【(A)* (B) 】% MOD】* (C)% MOD

具体操作就是:将每一次乘积的结果都取模,这样可以保证每一个乘数不会超限

最终实现代码:

#include <bits/stdc++.h> 
using namespace std;
int main(){
	//阶乘之和
	int n;
	cin>>n;
	if(n>=25) n = 25;
	int factorial = 1;
	int ans = 0;
	for(int i=1;i<=n;++i)
	{
		factorial *= i;
		factorial %= 1000000;  
		ans += factorial;
		ans %= 1000000;
	}
	cout<<ans<<endl;
	printf("time is %.2lf\n",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hskwcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值