【问题标题】:Calculating number of terms that should be added to get the required sum in series计算应添加的项数以获得所需的系列总和
【发布时间】:2017-06-17 23:25:13
【问题描述】:

我有一个类似系列的几何级数:

S = x1 + x2 + .....    xn (mod m)
where xi = (x(i-1))*r (mod m) for i>1 and x1=1  , 2<=m<10^9, 1<=r<m, 1<=S<m, 1<=n<p

这里m是一个素数,r,m,S是已知的。

Property of r : If we form a set of r (mod m), r^2 (mod m), ..., r^(m-1) (mod m) then it will contain all the numbers form 1 to m-1.

我想找到n 的值(如果可能的话)。我不能在这里应用几何级数 (GP) 公式,所以我做了一个替代算法,假设这些幂将使循环长度远小于n-1。我想找到一种模式,使系列重复自身,但这种循环模式只发生在某些r's 中,所以我没有这样做。当然,将循环设置到m 的天真方法不会起作用,因为它太大了,因此在终止之前需要很长时间。

我发现了一个类似的问题here。 但是在这个链接中,r 上没有属性可以使算法更快。我将此处给出的所有答案都应用到了我的代码中,但没有一个可以根据需要降低其复杂性。

我知道我必须以某种方式使用r 的属性来制定有效的算法,但我不知道如何。

那么我们可以找到任何其他模式,或者我们可以利用这个属性来获得最有效的算法吗? (基本上我不想遍历m。)所以请给我一个找到n的有效算法的想法。

【问题讨论】:

  • 您写道:r,r^2,....r^(n-1) then it will contain all the numbers [from] 1 to m-1。你的意思是r (mod m), r^2 (mod m), ..., r^(n-1) (mod m)
  • @ljeabmreosn 是的!我更新了,所以其他人没有这个疑问! :) PS: 权力是m 而不是n
  • 另外,xi = (x(i-1))*r (mod m) for i&gt;1 and x1=1 不是暗示S = 1 + r + r^2 + r^3 + ... + r^n (mod m)
  • 我们可以在某个地方聊天,我可以给你看照片吗?如果a1 + (a1*r)%m + ((a1*r)%m*r)%m + ... . 在这如果我参加第三届......那么你可以写((a1%m)*(r%m))%m * (r%p))%m = (a*r^2)%m...So a1 + (a1*r)%m + (a1*r^2)%m.. a1*r^(n-1)%m.... = > 你的输出直到r^(m-1) 虽然......然后你可以用@的总和替换它们987654343@.我认为并找到了总和,但它仍然在要求之前终止并且在某些测试用例中显示错误。我们可以在 facebook 或 gmail 上交谈吗??
  • 我不能,因为我必须有 20 声望才能在那里聊天。我是 stackoverflow 的新手。

标签: python algorithm time-complexity series number-theory


【解决方案1】:

我相信我已经找到了解决方案。请注意,r 是由r 的属性给出的primitive root modulo m

考虑几何和S = 1 + r + r^2 + ... + r^n。然后我们把S写成S = (r^n - 1) / (r - 1)

好吧,我们想以 m 为模求解这个方程,因为我们已经给出了 Sr。所以我们需要解决:

   (r^n - 1) / (r - 1) = S (mod m)
=> r^n - 1 = S * (r - 1) (mod m)
=> r^n = S * (r - 1) + 1 (mod m)

我们现在遇到了Discrete Logarithm Problem

使用Baby-step Giant-step 算法,我们可以在O(sqrt(m)) 中解决这个问题,如果m 最多为10^9,这是可行的。下面是我在 Python 3 中的实现,answer(r, m, S) 给出了想要的答案:

from math import sqrt, ceil

def invmod(r, p):
    """
    solves x = r^(-1) modulo p
    Note: p must be prime
    """
    return pow(r, p-2, p)


def discrete_log(a, r, p):
    """
    solves r^x = a (mod m) for x
    using the baby-step giant-step algorithm:
    https://math.berkeley.edu/~sagrawal/su14_math55/notes_shank.pdf
    Note: r must be a primitive root modulo p
    """


    m = int(ceil(sqrt(p)))

    # compute 1, r, r^2, ..., r^(m-1) modulo p
    pows = {pow(r, mp, p): mp for mp in range(m)}

    # compute r^(-m) modulo p
    y = pow(invmod(r, p), m, p)

    # compute a, ay, ay^2, ..., until we find a number
    # already in pows
    for q in range(m):
        z = (a * pow(y, q, p)) % p
        if z in pows:
            return pows[z] + (q * m)

    raise Exception("discrete logarithm not found")


def answer(r, p, S):
    """
    if S = 1 + r + r^2 + ... + r^n (mod p),
    then answer(r, p, S) = n
    """
    a = (S * (r-1) + 1) % p
    return discrete_log(a , r, p)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    相关资源
    最近更新 更多