找到一个^ b ^ c ^ ... mod m

时间:2010-11-19 08:40:09

标签: algorithm math number-theory

我想计算:

B'SUP> C d mod m

你知道任何有效的方法,因为这个数字太大但a,b,c,...和m适合一个简单的32位int。

任何想法?


警告:这个问题与找到 b mod m不同。

另请注意, b c 与(a b c 不同。后者等于 bc 。指数是右关联的。

5 个答案:

答案 0 :(得分:20)

a b c mod m = a b c mod n mod m,其中n =φ( m)Euler's totient function

如果m是素数,那么n = m-1。

编辑:正如Nabb指出的那样,只有当a与m相互作用时才会成立。所以你必须先检查一下。

答案 1 :(得分:1)

  1. 因为对于任何关系a=x^y,关系对于您使用的数字基础(基数2,基数6,基数16等)是不变的。

  2. 由于mod N操作相当于提取基数N中的最低有效位(LSD)

  3. 由于基数N中结果A的LSD只能受基数N中X的LSD影响,而不能影响较高位置的数字。 (例如34 * 56 = 30 * 50 + 30 * 6 + 50 * 4 + 4 * 5 = 10 *(3 + 50 + 3 * 6 + 5 * 4)+ 4 * 6)

  4. 因此,从LSD(A)=LSD(X^Y)我们可以推断出

    LSD(A)=LSD(LSD(X)^Y)
    

    因此

    A mod N = ((X mod N) ^ Y) mod N
    

    (X ^ Y) mod N = ((X mod N) ^ Y) mod N)
    

    因此,您可以在每个功率步骤之前执行mod,这会将结果保持在整数范围内。


    这假定a不是负的,并且对于任何x ^ y,a ^ y< MAXINT


    这个答案回答了错误的问题。 (亚历)

答案 2 :(得分:1)

Modular Exponentiation是解决这个问题的正确方法,这里有一点提示:

找到 b c d %m 你必须从计算开始 a%m,然后是 b %m,然后是 b c %m,然后是 b c d %m ...(你明白了)

要找到 b %m,您基本上需要两个想法:[设B =楼层(b / 2)]

  • a b =(a B 2 如果b是偶数OR a b =(a B 2 * a如果b是奇数。
  • (X * Y)%m =((X%m)*(Y%m))%m
    (%= mod)

    因此,
    如果b是偶数 a b %m =(a B %m) 2 %m
    或者如果b是奇数
    a b %m =((( B %m) 2 )*(a%m))%m
    < / p>

    因此,如果您知道 B 的值,则可以计算该值。

    要找到 B ,请应用类似方法,将B除以1,直到达到1。

    e.g。计算16 13 %11:

    16 13 %11 =(16%11) 13 %11 = 5 13 %11 =(5 6 %11)*(5 6 %11)*(5%11)&lt; ----(I)
    找到5 6 %11:
    5 6 %11 =((5 3 %11)*(5 3 %11))%11&lt; -----( II)
    找到5 3 %11:
    5 3 %11 =((5 1 %11)*(5 1 %11)*(5%11))%11 <登记/> =(((5 * 5)%11)* 5)%11 =((25%11)* 5)%11 =(3 * 5)%11 = 15%11 = 4
    将该值插入(II)给出 5 6 %11 =(((4 * 4)%11)* 5)%11 =((16%11)* 5)%11 =(5 * 5)%11 = 25% 11 = 3
    将该值插入(I)给出 5 13 %11 =((3%11)*(3%11)* 5)%11 =((9%11)* 5)%11 = 45%11 = 4 >

    这样5 13 %11 = 4
    有了这个你可以计算出任何形式 5 13 %11等等...

  • 答案 3 :(得分:0)

    查看A^X mod M增加X时的行为。它最终必须进入一个循环。假设周期的长度为P,并在N步之后开始。然后X >= N隐含A^X = A^(X+P) = A^(X%P + (-N)%P + N) (mod M)。因此,我们可以通过计算A^B^C计算y=B^C, z = y < N ? y : y%P + (-N)%P + N, return A^z (mod m)

    请注意,我们可以递归地将此策略应用于幂树,因为派生的等式具有指数&lt; M或涉及较小指数塔的指数,且股息较小。

    唯一的问题是,如果您能够有效地计算NP给定AM。请注意,高估N很好。我们可以将N设置为M,事情就会成功。 P有点困难。如果AM是不同的素数,那么P=M-1。如果A包含所有M的素数因子,那么我们会陷入0和P=1。我会把它作为练习来解决这个问题,因为我不知道如何。

    ///Returns equivalent to list.reverse().aggregate(1, acc,item => item^acc) % M
    func PowerTowerMod(Link<int> list, int M, int upperB = M)
        requires M > 0, upperB >= M
        var X = list.Item
        if list.Next == null: return X
        var P = GetPeriodSomehow(base: X, mod: M)
        var e = PowerTowerMod(list.Next, P, M)
        if e^X < upperB then return e^X //todo: rewrite e^X < upperB so it doesn't blowup for large x
        return ModPow(X, M + (e-M) % P, M)
    

    答案 4 :(得分:0)

    Tacet的回答很好,但可以进行大量的简化。

    x,mod m的幂是预周期的。如果x是m的相对素数,x的幂是周期性的,但即使没有这个假设,周期之前的部分也不长,最多是m的素数因式分解中的指数的最大值,最多为log_2 m 。周期的长度除以phi(m),实际上是lambda(m),其中lambda是Carmichael's function,最大乘法次序mod m。这可以显着小于phi(m)。 Lambda(m)可以从m的素因数分解快速计算,就像phi(m)一样。 Lambda(m)是在m的素因数分解中的所有素数p_i ^ e_i上的λ(p_i ^ e_i)的GCD,并且对于奇次幂,λ(p_i ^ e_i)= phi(p_i ^ e ^ i)。 lambda(2)= 1,lamnda(4)= 2,lambda(2 ^ n)= 2 ^(n-2),更大的幂为2。

    将modPos(a,n)定义为{0,1,..,n-1}中a的同余类的代表。对于非负a,这只是%n。对于负数,由于某种原因,%n被定义为负数,因此modPos(a,n)是(a%n)+ n。

    将modMin(a,n,min)定义为与mod n至少为min的最小正整数。对于正数,您可以将其计算为min + modPos(a-min,n)。

    如果b ^ c ^ ...小于log_2 m(并且我们可以通过递归取对数来检查这个不等式是否成立),那么我们可以简单地计算一个^ b ^ c ^ ...否则,a ^ b ^ c ^ ... mod m = a ^ modMin(b ^ c ^ ...,lambda(m),[log_2 m]))mod m = a ^ modMin(b ^ c ^ ... mod lambda(m ),lambda(m),[log_2 m])。

    例如,假设我们要计算2 ^ 3 ^ 4 ^ 5 mod 100.注意3 ^ 4 ^ 5只有489个数字,所以这可以通过其他方法来实现,但是它足够大了你不想直接计算它。但是,通过我在这里给出的方法,您可以手动计算2 ^ 3 ^ 4 ^ 5 mod 100.

    从3 ^ 4 ^ 5&gt; log_2 100,

    2^3^4^5 mod 100 
    = 2^modMin(3^4^5,lambda(100),6) mod 100 
    = 2^modMin(3^4^5 mod lambda(100), lambda(100),6) mod 100
    = 2^modMin(3^4^5 mod 20, 20,6) mod 100.
    

    让我们计算3 ^ 4 ^ 5 mod 20.由于4 ^ 5&gt; log_2 20,

    3^4^5 mod 20 
    = 3^modMin(4^5,lambda(20),4) mod 20 
    = 3^modMin(4^5 mod lambda(20),lambda(20),4) mod 20
    = 3^modMin(4^5 mod 4, 4, 4) mod 20
    = 3^modMin(0,4,4) mod 20
    = 3^4 mod 20
    = 81 mod 20
    = 1
    

    我们可以将其插入以前的计算中:

    2^3^4^5 mod 100 
    = 2^modMin(3^4^5 mod 20, 20,6) mod 100
    = 2^modMin(1,20,6) mod 100
    = 2^21 mod 100
    = 2097152 mod 100
    = 52.
    

    注意2 ^(3 ^ 4 ^ 5 mod 20)mod 100 = 2 ^ 1 mod 100 = 2,这是不正确的。你不能减少到基数权力的预期部分。