Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm (x^2+;x+;1)^n中x^m项的决定系数为偶数或奇数_Algorithm_Math_Algebra_Number Theory_Mod - Fatal编程技术网

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