E - Geometric Progression

文章介绍了如何解决在atcoder.jp上的E-GeometricProgression题目,通过观察和分析,提出使用线性算法和二进制优化方法来计算从0到m-1的次方和。在处理大数x(1e12)时,避免直接暴力计算,转而采用二进制表示,逐位处理并更新答案和乘数,最终给出相应的C++代码实现。

E - Geometric Progression (atcoder.jp)

这个题要求从 0 到 m - 1 的次方和。通过写下样例观察不难发现,这道题可以线性的做,又因为 x 的大小是 1e12 ,直接暴力肯定是不行的,所以这个题我们可以想到二进制优化,像如果这个数表示成二进制的话,最多 2 的 40次方就肯定够用了。所以这个题可以二进制来做。

然后观察这个求和的序列,我们不难发现,后面的次方一定大于前面的次方,这样我们可以考虑从第一个开始,每次加上一个数,然后乘上一个数。比如说一开始是 3 ^ 0 ,然后加上一个数再乘就变成 3 ^ 1 + 3 ^ 0 了。所以这个题的关键是处理怎么二进制表示这个加上的这个数。

首先我们容易想到的是这个 x 一定可以用二进制表示,每次 >>= 1, 然后判断是不是 &1 ,来进行相乘,那么那个加的数呢,那个加的数我们也要采取二进制的方法,假设一开始是 uu ,然后每次uu = uu * (1 + a)  % m, 由于这个二进制的关系,每次我们都要让 uu 加上这个数。

代码如下:

#include <bits/stdc++.h>
#define int long long 
using namespace std;
signed main()
{
	int a, x, m; cin >> a >> x >> m;
	int ans = 0;
	int uu = 1;
	while (x)
	{
		if (x & 1)
			ans = (ans * a + uu) % m;
		uu = uu * (a + 1) % m;
		a = (a * a) % m, x >>= 1;
	}
	cout << ans << "\n";
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值