我如何获得GCD(2 ^ a [i] -1,2 ^ a [j] -1) 1 <= a [x] <= 100
from fractions import gcd
powj=pow(2,n[j])-1
powk=pow(2,n[k])-1
gcdjk=gcd(powj,powk)
会导致大数字出现问题并产生运行时错误 我看不到2 ^ i-1值中的模式,除了没有除1以外的其他因素的素数。
i 2^i -1
--------------
1 1 = 1
2 3 = 1,3
3 7 = 1,7
4 15 = 1,3,5,15
5 31 = 1,31
6 63 = 1,3,7,9,21,63
7 127= 1,127
8 255= 1,3,5,15,17,51,85,255
编辑:仅需要为表格2 ^ i-1的数字解决此问题。以下是代码:
import sys
import math
from fractions import gcd
t=int(input())
for i in range(0,t):
door=0
c=int(input())
n = map(int,sys.stdin.readline().split(' '))
for j in range(0,c-1):
for k in range(j+1,c):
if( gcd(n[j],n[k]) == n[k]):
powj=pow(2,n[j])-1
powk=pow(2,n[k])-1
gcdjk=gcd(powj,powk)
if(gcdjk==powk):
door = door+1
else:
door = door-gcdjk
print (door)
输入样本:
2
3
10 2 3
2
3 5
约束:
1<=T<=20
1<=ArraySize<=10^5
1<=a[i]<=100
答案 0 :(得分:4)
考虑binary GCD algorithm。如果两个操作数的形式为2 i -1,则可以大大简化。
首先,第一步显然没有零,所以你直接进入循环。
在循环中,在减法中,您有两个数字,形式为2 i -1,左侧比右侧大,因此减法只是重置y
中的低位位数与x
中设置的位数一样多,即减法等效于y &= ~x
。减法之后立即将y
向右移动其中的尾随零的数量,因此您再次使用2 i -1的形式,但popcnt(x)
更短
从这一点可以看出,只有长度(即指数)才有意义,而且身份是 gcd(2 a -1,2 b -1)= 2 gcd(a,b) -1来自它。
答案 1 :(得分:1)
这些数字非常小。使用Python内置的bignum处理,它们完全在Euclidean算法fractions.gcd
使用的范围内:
>>> fractions.gcd(2**50-1, 2**100-1)
1125899906842623L
您的错误来自其他地方。当您尝试迭代10000个元素列表中的所有数字对时,您甚至可能只是超时。有近5000万这样的对。根据您获得的时间长短,您的算法可能过于缓慢。
答案 2 :(得分:0)
这是一种简单的方法,你可以使用euclid算法来解决2的幂而不实际评估它们: -
我们需要找到一个%b来解决使用欧几里德算法的GCD: -
a = 2 ^ x-1 b = 2 ^ y-1
和a&gt; b
我们需要表达a = k * b + m,其中m
假设k = 2 ^(x-y)
2 ^ x - 1 = 2 ^(x-y)*(2 ^ y-1)+ m,m = 2 ^(x-y)-1
因此
a%b = m = 2 ^(x-y)-1
因此m再次具有两个减1形式的相似幂,因此我们可以 在其上应用欧几里德算法。
进一步分析:
a = 2^x-1
b = 2^y-1
GCD(a,b) = F(x,y)
where
F(x,y) = x if x==y
F(x,y) = F(x-y,y) if x > y
F(x,y) = F(x,y-x) if y < x
From further analysis F(x,y) = GCD(x,y)
参考: - GCD