博客
关于我
A^X mod P(简单数论 + 思维打表)
阅读量:253 次
发布时间:2019-03-01

本文共 2078 字,大约阅读时间需要 6 分钟。

为了高效计算给定的递归函数f(x)的和,我们可以将其分解为两个预处理数组,从而优化计算过程。以下是详细的分析和解决方案:

问题分析

我们需要计算一个递归函数f(x)的和,并对其进行幂运算和模运算。由于直接计算会导致时间复杂度过高,我们需要一种优化方法。

递归函数f(x)的定义

f(1) = 1

对于x > 1,f(x) = (a * f(x-1) + b) mod m
这表明f(x)遵循一个线性递推关系,可能导致快速增长。

需要计算的表达式

计算S = A^{f(1)} + A^{f(2)} + ... + A^{f(n)} mod p

直接计算每个f(x)并求幂会导致计算量过大,特别是当n很大时。

优化方法

我们可以将计算分解为两个部分,利用快速幂和模运算的性质来优化:

  • 预处理数组sum1和sum2

    • sum1[i] = A^i mod p
    • sum2[i] = A^{1e5 * i} mod p
      这里,M = 1e5,是一个合理的模数。
  • 分解f(x)的计算:f(x) = a * f(x-1) + b mod m

    这个递推关系可以分解为:
    f(x) = a^{x-1} * (a + b) - b
    但由于模运算的性质,我们可以将其表示为:
    f(x) = a^{k} * x + b * (a^{k} - 1) / (a - 1)
    通过这种分解,我们可以利用预处理数组sum1和sum2来计算每个f(x)。

  • 计算总和:S = sum_{x=1}^{n} A^{f(x)} mod p

    由于f(x) = a^{k} * x + b,我们可以将其分解为:A^{f(x)} = sum1[i] * sum2[j] mod p
    其中,i = f(x) mod M,j = f(x) / M
    这样,总和可以分解为sum1和sum2的和,避免了直接计算每个f(x)的高复杂度。

  • 代码实现

    以下是实现这一优化的代码:

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;#define M (int)1e5ll n, A, K, a, b, m, p;ll sum1[M + 5];ll sum2[M + 5];void init() { sum1[0] = 1; sum1[1] = A % p; for (int i = 2; i <= M; ++i) { sum1[i] = (sum1[i - 1] * A) % p; } sum2[0] = 1; sum2[1] = sum1[M]; for (int i = 2; i <= M; ++i) { sum2[i] = (sum2[i - 1] * sum2[1]) % p; }}ll f() { ll fx = K % m; ll sum = 0; for (ll i = 1; i <= n; ++i) { if (fx == 0) { sum = (sum + sum1[0] * sum2[0]) % p; } else { int k = fx / M; int rem = fx % M; sum = (sum + sum1[rem] * sum2[k]) % p; } fx = (a * fx + b) % m; } return sum % p;}int main() { int T; scanf("%d", &T); for (int ca = 1; ca <= T; ++ca) { cin >> n >> A >> K >> a >> b >> m >> p; init(); ll ans = f(); printf("Case #%d: %lld\n", ca, ans); } return 0;}

    解释

  • 预处理数组

    • sum1[i] 计算A的i次幂模p。
    • sum2[i] 计算A的1e5次幂模p的i次幂。这样,sum2[i]实际上是A^{1e5*i} mod p。
  • 递归函数f(x)的计算

    • 对于每个x,计算f(x)并分解为i和j,分别表示模M的部分和高位部分。
    • 然后,利用预处理数组sum1和sum2来计算A^{f(x)} mod p。
  • 总和计算

    • 遍历每个x,计算对应的A^{f(x)} mod p,并累加到总和中。
    • 由于预处理的sum1和sum2数组已经预先计算,单次循环的时间复杂度为O(n)。
  • 这种方法通过预处理和分解,显著减少了计算量,使得问题在合理的时间内解决。

    转载地址:http://tyht.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现memset函数功能(附完整源码)
    查看>>
    Objective-C实现merge insertion sort合并插入排序算法(附完整源码)
    查看>>
    Objective-C实现merge sort归并排序算法(附完整源码)
    查看>>
    Objective-C实现mergesort归并排序算法(附完整源码)
    查看>>
    Objective-C实现MidpointIntegration中点积分算法 (附完整源码)
    查看>>
    Objective-C实现miller rabin米勒-拉宾素性检验算法(附完整源码)
    查看>>
    Objective-C实现Miller-Rabin素性测试程序(附完整源码)
    查看>>
    Objective-C实现Miller-Rabin素性测试程序(附完整源码)
    查看>>
    Objective-C实现min cost string conversion最低成本字符串转换算法(附完整源码)
    查看>>
    Objective-C实现MinhashLSH算法(附完整源码)
    查看>>
    Objective-C实现MinhashLSH算法(附完整源码)
    查看>>
    Objective-C实现MinHeap最小堆算法(附完整源码)
    查看>>
    Objective-C实现minimum coin change最小硬币找零算法(附完整源码)
    查看>>
    Objective-C实现minimum cut最小切割流算法(附完整源码)
    查看>>
    Objective-C实现minimum partition最小分区算法(附完整源码)
    查看>>
    Objective-C实现Minimum Priority Queu最小优先级队列算法(附完整源码)
    查看>>
    Objective-C实现Minimum Vertex Cover最小顶点覆盖算法(附完整源码)
    查看>>
    Objective-C实现MinimumCostPath最小成本路径算法(附完整源码)
    查看>>
    Objective-C实现min_heap最小堆算法(附完整源码)
    查看>>
    Objective-C实现mobius function莫比乌斯函数算法(附完整源码)
    查看>>