加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 两个二项式系数的GCD,模数为10 ^ 9 7

发布时间:2020-12-16 07:23:41 所属栏目:百科 来源:网络整理
导读:给出0≤k≤n≤500000,0≤l≤m≤500000. 我需要计算GCD(C(n,k),C(m,l))模10 ^ 9 7. 我的尝试: 我考虑过使用fourmula的技巧: C(n,k)= n *(n-1)* … *(n-k 1)/ k! 例如,假设l = k: GCD(C(n,l))= = GCD(n *(n-1)* … *(n-k 1)/ k!,m *(m-1)* … *(m-l 1)/ l
给出0≤k≤n≤500000,0≤l≤m≤500000.

我需要计算GCD(C(n,k),C(m,l))模10 ^ 9 7.

我的尝试:

我考虑过使用fourmula的技巧:
C(n,k)= n *(n-1)* … *(n-k 1)/ k!

例如,假设l> = k:
GCD(C(n,l))=
= GCD(n *(n-1)* … *(n-k 1)/ k!,m *(m-1)* … *(m-l 1)/ l!)=
= GCD(n *(n-1)* … *(nk 1)*(k 1)* … * l / l!,m *(m-1)* … *(ml 1) / l!)=
= GCD(n *(n-1)* … *(nk 1)*(k 1)* … * l,m *(m-1)* … *(ml 1))/ l !

反转l!用二进制求幂到10 ^ 9 5很好,但我不知道如何继续.

这(k 1)* … * l部分破坏了一切.如果在乘数之间存在交集,我可以找到一些好处
n *(n-1)* … *(n-k 1)和m *(m-1)* … *(m-l 1),
但如果没有,整个GCD必须包含在这个(k 1)* … * l部分中.

接下来是什么?使用原生GCD算法保留剩余乘数?
太长了因为需要计算它们的产物,所以上面的操作看起来毫无意义.

我是正确的吗?
是否有一些技巧可以解决这个问题?

解决方法

有了juvian的建议,这很简单.我怎么没想出分解的想法!

我的C代码如下:

#include <iostream>
#include <algorithm>

#define NMAX 500000
#define MOD 1000000007

using namespace std;


long long factorial(long long n)
{
    long long ans = 1;
    for (int i = 2; i <= n; i++)
        ans = ans * i % MOD;
    return ans;
}

long long binPow(long long num,int p)
{
    if (p == 0)
        return 1;

    if (p % 2 == 1)
        return binPow(num,p - 1) * num % MOD;
    if (p % 2 == 0)
    {
        long long b = binPow(num,p / 2);
        return b * b % MOD;
    }
}

void primesFactorize(long long n,long long primes[])
{
    for (int d = 2; d * d <= n; d++)
        while(n % d == 0)
        {
            n /= d;
            primes[d]++;
        }
    if (n > 1) primes[n]++;
}

long long primes1[NMAX];
long long primes2[NMAX];

int main()
{
    long long n,k,m,l;

    cin >> k >> n >> l >> m;

    if (k > l)
    {
        swap(n,m);
        swap(k,l);
    }

    for (int i = n - k + 1; i <= n; i++)
        primesFactorize(i,primes1);

    for (int i = k + 1; i <= l; i++)
        primesFactorize(i,primes1);

    for (int i = m - l + 1; i <= m; i++)
        primesFactorize(i,primes2);

    for (int i = 2; i <= max(n,m); i++)
        primes1[i] = min(primes1[i],primes2[i]);

    long long ans = 1;
    for (int i = 2; i <= max(n,m); i++)
        for (int j = 1; j <= primes1[i]; j++)
            ans = ans * i % MOD;

    ans = ans * binPow(factorial(l),MOD - 2) % MOD;

    cout << ans << endl;
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读