在SPOJ INCSEQ中获得WA - 增加子序列

时间:2015-05-19 09:12:26

标签: c++ c algorithm data-structures

我不知道为什么我会在第10个案件中获得WA, 我使用了BIT和组合。 问题链接:SPOJ INCSEQ

问题细节:给定N(1≤N≤10,000)个整数S1,...,SN(0≤Si<100,000)的序列,计算长度为K(1≤K)的S的增加子序列的数量≤50且K≤N);也就是说,K元组i1,...,iK的数量使得1≤i1<1。 ......&lt; iK≤N且Si1 < ......&lt;植

这是My Code

我认为使用Mod功能的nCr存在问题。    他们没有给出失败的测试用例,所以我没有任何失败的测试用例。

// Here i compute nCk
unsigned long long combination(ll n,ll k)
{
    unsigned long long ans=1;
    k=k>n-k?n-k:k;
    ll j=1;
    for(; j<=k; j++,n--)
    {
        if(n%j==0)
        {
            ans*=n/j;
        }
        else if(ans%j==0)
        {
            ans=ans/j*n;
        }
        else
        {
            ans=(ans*n)/j;
        }
    }
    return ans%mod;
}

plz help

1 个答案:

答案 0 :(得分:1)

您的combination方法错误,因为对于大数字,nCr的结果将大于long long范围。

因此,有效地使用模数,我们可以避免在这种情况下溢出

我们知道还有另一种计算nCr的方法

我们知道

nCr = (n - 1)C(r - 1) + (n - 1)Cr

由于k <= 50这个很小,我们可以按如下方式计算我们的组合表c

int[][]c = new int[n + 1][k+1];
c[0][0] = 1;

for (int i = 1; i <= n; i++) {
    c[i][0] = 1;
    if(i <= k)
        c[i][i] = 1;
    for (int j = 1; j <= k; j++) {
        c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
        c[i][j] %= mod;
    }
}

mod操作将确保我们的结果永远不会溢出。