Algorithm (x^2+;x+;1)^n中x^m项的决定系数为偶数或奇数
对于给定的整数Algorithm (x^2+;x+;1)^n中x^m项的决定系数为偶数或奇数,algorithm,math,algebra,number-theory,mod,Algorithm,Math,Algebra,Number Theory,Mod,对于给定的整数n和m,确定(x^2+x+1)^n中x^m项的系数是偶数还是奇数? 例如,如果n=3,m=4,(x^2+x+1)^3=x^6+3x^5+[[6x^4]]+7x^3+6x^2+3x+1,则x^4项的系数为6(=偶数)。 n和m大到10^12,我想在几秒钟内计算,所以不能用线性时间计算。 你有什么有效的算法吗?好的,我刚想到一个解决方案。下面是: 把这个方程写成n次,(a.x^2+b.x^1+c)。(a.x^2+b.x^1+c)…n次。a、 b和c是我通常假设的常数 现在,我们必
n
和m
,确定(x^2+x+1)^n中x^m
项的系数是偶数还是奇数?
例如,如果n=3,m=4,(x^2+x+1)^3=x^6+3x^5+[[6x^4]]+7x^3+6x^2+3x+1
,则x^4
项的系数为6(=偶数)。
n
和m
大到10^12,我想在几秒钟内计算,所以不能用线性时间计算。
你有什么有效的算法吗?好的,我刚想到一个解决方案。下面是:
把这个方程写成n次,(a.x^2+b.x^1+c)。(a.x^2+b.x^1+c)…n次。a、 b和c是我通常假设的常数
现在,我们必须从每一项中选取一项,这样所有这些项的乘法结果就是x^m
我现在可以说,我们必须找到方程的解,t1.2+t2=m
,其中t1
不是x^2
和t2
的出现。这是因为t1
和t2
将使术语的形式为k.x^m
(k为常数)。这是找到这个方程的积分丢番图解,也就是找到所有满足的{t1,t2}
现在,我们必须应用一些置换来求系数。假设上一步有一个解{1,2}
,那么对于这个diad,系数将是(1^1.nC1)。(2^2.(n-1)C2)
,它将是系数的组成部分之一。如果你把所有这些与丢番图解对应的系数项求和,你就会得到系数
实现上述算法需要一些时间,所以我已经发布了步骤
注意:我搜索了一点,有各种算法用于丢番图解。以下是一篇与此相关的帖子:
编辑:作为一个例子
比方说,我们有一个方程,(x^2+x^1+x^1)^3
,我们必须找到x^3
的系数。因此,我们有m=3
单独编写方程式是为了直观地看到步骤。是,
(x^2+x^1+x^1)。(x^2+x^1+x^1)。(x^2+x^1+x^1)
现在,我们要从每一个中选择{x^2,x^1,1}
。有几种方法可以选择它来进行形式的乘法,x^3
为了解决这个问题,我们可以写出方程,2.a+b=3
,其中a是x^2被拾取的次数,b是x被拾取的次数。这个方程的解是,{0,3}
和{1,1}
。现在,因为我们还必须考虑选择它们的顺序,我们将在下一步应用组合数学
系数为,2^0.3C0.3^3.3C3+2^1.3C1.3^1.2C1
。现在在这里,
在第一项中,2^0.3C0.3^3.3C3
,3C0
意味着用3C3
选择0次出现的x^2
意味着3次出现的x,这将给出x^3
,但我们也用2^0
相乘,因为2是等式中x^2
的系数,同样,3^3
因为3是x的系数。类似地,您可以使用与{1,1}
这加起来是63,您可以通过手动乘以来验证,您将得到63
希望我是清楚的。
< P>注意,如果一个人只关心x^ m的系数是奇数还是偶数,可以考虑多项式系数是有限域F2的元素。< /P>
注意(1+x+x^2)^2=(1+x^2+x^4)mod 2
,因为交叉项都是偶数。事实上,如果n是2的幂,那么(1+x+x^2)^n=(1+x^n+x^2n)mod 2
对于一般n,将其写成2的幂和(即二进制)
然后将与2的每个幂对应的幂相乘:
(1+x+x^2)^n = (1+x^(2^a1)+x^(2^(a1+1))) * ((1+x^(2^a2)+x^(2^(a2+1))) * ...
现在,这个乘积中的每个项只有3个因子,如果n以10^12为界,则最多有35或36个因子。所以很容易将它们相乘
下面是一些实现此功能的Python代码:
# poly_times computes the product of polynomials
# p and q over the field F2. They are each
# represented by a set of non-zero coefficients.
# For example set([0, 2, 5]) corresponds to x^0 + x^2 + x^5.
def poly_times(p, q):
result = set()
for i in p:
for j in q:
if i+j in result:
result.remove(i+j)
else:
result.add(i+j)
return result
# Return the coefficient of x^m in (1+x+x^2)^n.
def coeff(n, m):
prod = set([0])
i = 0
while n:
if n % 2:
prod = poly_times(prod, [0, 2**i, 2**(i+1)])
i += 1
n >>= 1
return 1 if m in prod else 0
for m in xrange(10):
print m, coeff(3, m)
print coeff(1947248745, 1947248745034)
优化
对于设置了大量位的n,当n接近10^12时,速度会变得太慢
但是,我们可以通过将多项式幂分为两部分,然后在最后一步中找到m
的系数,而不是通过进行完整的多项式乘法,而是通过计算每个部分中与m之和的系数对,来大大加快速度。这是优化的系数
:
# poly_times computes the product of polynomials
# p and q over the field F2. They are each
# represented by a set of non-zero coefficients.
# For example set([0, 2, 5]) corresponds to x^0 + x^2 + x^5.
# Coefficients larger than m are discarded.
def poly_times(p, q, m):
result = set()
for i in p:
for j in q:
if i + j > m:
continue
if i+j in result:
result.remove(i+j)
else:
result.add(i+j)
return result
# Return the coefficient of x^m in (1+x+x^2)^n.
def coeff(n, m):
if m > 2*n: return 0
prod = [set([0]), set([0])]
i = 0
while n:
if n % 2:
prod[i//20] = poly_times(prod[i//20], [0, 2**i, 2**(i+1)], m)
i += 1
n >>= 1
s = 0
for x in prod[0]:
s += m-x in prod[1]
return s % 2
for m in xrange(10):
print m, coeff(3, m)
print coeff(0xffffffffff, 0xffffffffff)
请注意,这可以在几秒钟内计算出coeff(0xffffffff,0xffffffffff)
,并且0xffffffffff
大于10**12。兴趣系数取决于从x²+x+1中选择n项的方式的数量,以便所选项的幂和为m。这些方法可以分组为具有相同数量的选定x²术语和x术语的组(从中选择1的次数如下)
设a为x²项的数量,b为x项的数量,c为特定组中1项的数量
那么以下等式成立:
2a+b=m
a+b+c=n
显然,通常有几个组的a、b、c值不同。确定a后,还将确定b和c的值。因此,只需迭代a的可能值即可获得所有组
如果要编写蛮力算法来获取系数本身,则在Python中会如下所示:
defcombi(n,k):#从n个元素中获取k个元素的方法的数量
输入数学
f=数学阶乘
返回f(n)//f(k)//f(n-k)
def get_系数(n,m):
如果m>n*2或n<0或m<
# poly_times computes the product of polynomials
# p and q over the field F2. They are each
# represented by a set of non-zero coefficients.
# For example set([0, 2, 5]) corresponds to x^0 + x^2 + x^5.
# Coefficients larger than m are discarded.
def poly_times(p, q, m):
result = set()
for i in p:
for j in q:
if i + j > m:
continue
if i+j in result:
result.remove(i+j)
else:
result.add(i+j)
return result
# Return the coefficient of x^m in (1+x+x^2)^n.
def coeff(n, m):
if m > 2*n: return 0
prod = [set([0]), set([0])]
i = 0
while n:
if n % 2:
prod[i//20] = poly_times(prod[i//20], [0, 2**i, 2**(i+1)], m)
i += 1
n >>= 1
s = 0
for x in prod[0]:
s += m-x in prod[1]
return s % 2
for m in xrange(10):
print m, coeff(3, m)
print coeff(0xffffffffff, 0xffffffffff)
(1 + x + x^2)^{2^i} = 1 + x^{2^i} + x^{2^{2 i}}
(1 + x + x^2)^n
= prod_i ((1 + x + x^2)^{2^i n_i})
where n = sum_i n_i 2^i and n_i in {0, 1} for all i
(i.e., n_i is the binary representation of n
= prod_i (1 + x^{2^i n_i} + x^{2^i 2 n_i})
= prod_i sum_{m_i = 0}^{2 n_i} x^{2^i}
= sum_{(m_i)} prod_i x^{2^i m_i}
taken over sequences (m_i) where 0 ≤ m_i ≤ 2 n_i.
a (0:0:nm') -> a nm' [emit 0]
a (1:0:nm') -> a nm' [emit 0]
-> b nm' [emit 2]
a (1:1:nm') -> a nm' [emit 1]
b (0:1:nm') -> a nm' [emit 0]
b (1:0:nm') -> b nm' [emit 1]
b (1:1:nm') -> a nm' [emit 0]
-> b nm' [emit 2]
def trinomial_mod_two(n, m):
a, b = 1, 0
while m:
n1, n = n & 1, n >> 1
m1, m = m & 1, m >> 1
if n1:
if m1:
a, b = a ^ b, b
else:
a, b = a, a ^ b
elif m1:
a, b = b, 0
else:
a, b = a, 0
return a
def trinomial_mod_two_branchless(n, m):
a, b = 1, 0
while m:
n1, n = n & 1, n >> 1
m1, m = m & 1, m >> 1
a, b = ((n1 | ~m1) & a) ^ (m1 & b), ((n1 & ~m1) & a) ^ (n1 & b)
return a