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

问题描述:

样例:

实现解释:

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

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

等比数列分治求和: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;
}

  

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

时间: 2024-10-09 18:39:50

题解:2018级算法第一次练习赛 等比数列求和的相关文章

题解:2018级算法第一次练习赛 妙妙趣排序

问题描述: 样例: 实现解释: 针对这个问题,首先可以想到有两种解决方法:构造全排列然后分别筛选后进行判断,逆序判断. 而显然对于前者时间是一定不够的(10以上数字的全排列构建时间就已经很长了),所以需要进行逆序判断. 即如果是符合条件的数组,那么经过筛选器后一定会是一个即将排好序的数组.所以只需要对所有即将排好序的数组倒序通过筛选器,得到筛选前的数组再判断即可. 注意筛选器的处理有两种可能:不必更换和更换两个位置的值,所以在判断之前的筛选器时需要分别对更换前后进行判断. 而对于即将排好序的数组

题解:2018级算法第二次上机 Zexal的排座位

题目描述: 样例: 实现解释: 一道看似复杂但实际既是斐波那契变形的题目 知识点:递推,斐波那契 通过问题的描述,可以得到以下规律:(除了座位数为一时)男生坐最后时,倒数第二个一定是女生:女生坐最后,倒数第二个均可.转化:i个位置时男生结尾的情况数等于i-1个位置时女生结尾的情况数,i个位置时女生结尾的情况数等于i-1个位置时的总情况数. 于是便可得出两种解决方案:斐波那契变形和直接循环递推 斐波那契变形: i位置男生结尾的情况 = i-1位置女生结尾情况数 = i-2位置总情况数 i位置女生结

题解:2018级算法第二次上机 Zexal的流水线问题

题目描述: 样例: 实现解释: 最基础的流水线调度问题,甚至没有开始和结束的值 知识点:动态规划,流水线调度 实现方法即得出状态转移方程后完善即可,设a[][i]存储着第一二条线上各家的时间花费,t[][i]存储着i处进行线路切换的花费,f[][i]存储着各线在i处的最小花费. 则对每一个f[][i]应有如下的转移方程: f[0][1] = a[0][1]; f[1][1] = a[1][1]; f[0][i] = min(f[0][i-1]+a[0][i],f[1][i-1]+t[1][i-1

A1-2017级算法第一次上机练习赛 C AlvinZH去图书馆

题目描述 AlvinZH最近在看<冰与火之歌>系列,这天,他又看完了一本书,于是决定去图书馆再借一本.大家知道,在去图书馆的路上,有一条"扯蛋路".大概是这个样子的(秀一波拍照技术): AlvinZH从第一块石砖出发,接下来他可以走到第二块石砖或第三块石砖,有时候走的很不爽,甚至可以直接跨过两个石砖,到达第四块石砖,但是不能连续两次这种操作,因为这样...对身体不好.现在假设有一条含n块石砖的小路,请你计算出AlvinZH从第一块石砖出发有多少种安全的走法. 输入 输入将由

题解:2018级算法第二次上机 Zexal的钢管切割

题目描述: 样例: 实现解释: 经典钢管切割问题的变形:最赔钱切割 知识点:动态规划,钢管切割 实现方法即得出状态转移方程后完善为代码即可,先设数组price[i]存储着i长度钢管切割后的最小值,p[i]存储着i长度钢管不切割的值,price数组既是本问题的dp数组. 经过分析可知状态转移方程为: price[0] = 0; price[i] = min(p[1]+price[i-1],p[2]+price[i-2],...p[i-1]+price[1],p[i]); 因为price[i]已经是

题解:2018级算法第二次上机 Zexal的竞赛

题目描述: 样例: 实现解释: 一道需要一点思考的动态规划题目 知识点:动态规划,数据记录 首先将题目描述调整:分别输入不同分数的题目总分(便于后续计算),当获得了i分数的总分后无法获得i-1和i+1的总分. 于是便可先利用score[i]储存i分数的总分数,用dp[i]储存以前i个分数为范围进行题目选择时的最大可获得分数.dp便是动态规划所用的数组. 于是可得状态转移方程如下: dp[0] = score[0]; dp[1] = score[1]; dp[i] = max(dp[i-2]+sc

题解:2018级算法第三次上机 C3-Zexal的浩瀚星辰

题目描述: 样例: 实现解释: 一道结合了火箭发射的贪心题目 知识点: 贪心,优先队列 题目分析: 根据题目描述可知,延迟后时间是正常推进的,也就是假设共有n个火箭,推迟k小时.则在到达k+1小时时,每过一个小时只要火箭没发射完都会有k(如果k大于n就是有剩余数量)个火箭会遭受延迟的损失,显然这是必然的(因为到达k小时前的损失都已经确定了,无法改变). 那么依据题意只要使得每次这k个火箭的损失最小即可,而如何最小:让其中单位时间损失最大的火箭发射即可,这样一定比发射其他火箭的损失要小. 于是便可

题解:2018级算法第四次上机 C4-商人卖鱼

题目描述: 样例: 实现解释: 需要简单分析的贪心题 知识点: 贪心,自定义排序,提前存储 题目分析: 卖鱼,鱼卖出去需要时间,鱼没被卖出去之前需要吃饲料 则有,如果卖a鱼的话b鱼会吃饲料c份,而卖b鱼a鱼会吃d份,为了消耗更少的饲料,如果c比d小,则应该卖a鱼.而计算上即c = a.t*b.d,d = a.d*b.t. 因此需要做的就是依据上述公式对所有鱼的买卖优先级进行排序(排序的cmp函数实现有进行简单解释),然后按顺序计算需要的饲料数即可. 为了不再遍历计算卖鱼时的花费,这里用total

题解:2018级算法第四次上机 C4-最小乘法

题目描述: 样例: 实现解释: 和字符串处理结合的动态规划,个人认为比较难分析出状态转移方程,虽然懂了之后挺好理解的 知识点: 动态规划,字符串转数字 题目分析: 首先按照最基础:依据题意设计原始dp数组,这里根据描可知有三个数需要考虑:数字串开始,数字串结尾和之间插入的乘号数量,因此基础dp[i][j][k],分别为开始,结束脚标和乘号数. 然后推导:考虑到添加乘号,为了使状态转移方程简单,最后固定位置,因此可以考虑每次都在最后插入乘号,插入乘号的位置便可倒序确定.此时数字串的开始位置便可固定