lcm中c ++中数组中的所有数字

时间:2016-03-31 21:59:13

标签: c++ algorithm lcm

我遇到这段代码来计算数组中所有数字的最小公因数但却无法理解所使用的算法。这里使用__builtin_popcount有什么用来计算设置位数?

pair<long long, int> pre[200000];
long long a[25], N;

long long trunc_mul(long long a, long long b)
{
    return a <= INF / b ? a * b : INF;
}
void compute()
{
    int limit = 1 << N;
    limit--;
    for (int i = 1; i <= limit; i++)
    {
        long long lcm = 1;
        pre[i].second = __builtin_popcount(i);
        int k = 1;
        for (int j = N - 1; j >= 0; j--)
        {
            if (k&i)
            {
                lcm = trunc_mul(lcm / __gcd(lcm, a[j]), a[j]);

            }
            k = k << 1;
        }
        pre[i].first = lcm;
    }
    return;
}

1 个答案:

答案 0 :(得分:0)

您提供的代码最多可获得25个号码。对于每个数字子集,它将LCM计算为pre[i].first,将该子集中的数量计算为pre[i].second。子集本身表示为位掩码,因此要计算片段使用__builtin_popcount的子集中的元素数。它与LCM的计算无关。

使用相当标准的方法计算LCM:任何数字组的LCM等于它们的乘积除以它们的GCD。这正是剪辑所做的,使用内置GCD函数__gcd

k&ik = k<<1部分是要弄清楚哪些数字属于由位掩码表示的集合。如果您还没有完全理解它,请尝试通过在一张纸上或在调试器中运行此循环来查看i = 0b11010会发生什么。您会注意到k&i条件在第二次,第四次和第五次迭代时都是正确的,恰好是i在其二进制表示中具有1的位置。