码迷,mamicode.com
首页 > 编程语言 > 详细

题解:2018级算法第一次练习赛 等比数列求和

时间:2019-10-19 00:26:25      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:iostream   完整   超出   代码   col   还需   返回   logs   基础   

问题描述:

 技术图片

 

 技术图片

 

样例:

 技术图片

 

 

实现解释:

这里等比数列求和使用到的知识点包括:分治和快速幂

其中分治的方法和快速幂的方法是从博客中学习到的:

等比数列分治求和:https://blog.csdn.net/qq_35937273/article/details/82750298

快速幂方法:https://www.cnblogs.com/lca1826/p/6748372.html

结合到本题目中可参考完整代码。

在分治求和和快速幂之外取模操作的实现解释如下:

根据描述可知最后的值是很大的,所以需要取余,但实际上在计算的过程中就需要进行取余操作了。所以需要对快速幂函数和分治函数进行一下处理:

首先操作的基础公式(取余的等价式):

(a + b) % p = (a % p + b % p) % p (1)

(a - b) % p = (a % p - b % p + p) % p (2)

(a * b) % p = (a % p * b % p) % p (3)

a ^ b % p = ((a % p)^b) % p (4)

基于(4)首先需要对快速幂的乘数进行取模处理,然后在乘起来每一个值之前还需要对result进行取模处理,然后还需要对乘起来的值进行取模。这样才能保证快速幂得到的值得到了正常的取模处理(之前就是这里出错所以测试点只过了一个)

基于(1)和(3)需要对分治求和的返回结果分别进行取模处理。

 

坑点:

取余出现负数:数据超出了范围,是没正确取余导致的,因为正数取余不会得到负数。

 

完整代码:

#include<iostream>
using namespace std;
long long MOD = 987654323;
long long quickPow(long long q,long long cnt)
{
	long long mq = q%MOD;
	long long result = 1;
	while(cnt!=0)
	{
		if(cnt&1!=0)
		{
			result*=mq;
			result%=MOD;
		}
		mq*=mq;
		mq%=MOD;
//		if(cnt&1!=0)
//		{
//			result*=mq;
//		}
//		mq*=mq;
		cnt>>=1;
	}
	return result%MOD;
}
long long getSum(long long q,long long cnt)
{
	if(cnt == 0)
		return 1;
	
	if(cnt&1!=0)//奇数 
	{
		long long coef = 1+quickPow(q,(cnt+1)/2);
		return ((coef%MOD)*getSum(q,(cnt-1)/2))%MOD;
	}
	else//偶数
	{
		long long coef = 1+quickPow(q,cnt/2);
		return ((((coef%MOD)*getSum(q,cnt/2-1))%MOD)+quickPow(q,cnt))%MOD;
	} 
}
int main()
{
	long long cnt;
	cin >> cnt;
	long long n,a,q;
	while(cnt--)
	{
		cin >> n >> a >> q;
		cout << ((a%MOD)*getSum(q,n-1))%MOD << endl;
	}
	return 0;
}

  

题解:2018级算法第一次练习赛 等比数列求和

标签:iostream   完整   超出   代码   col   还需   返回   logs   基础   

原文地址:https://www.cnblogs.com/doUlikewyx/p/11701182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!