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

被折叠的 条评论
为什么被折叠?



