zoukankan      html  css  js  c++  java
  • 组合数相关问题

    http://blog.csdn.net/acdreamers/article/details/8037918

    上面的是lucas的讲解 感觉好清晰

    除以 阶乘就等于乘以逆元 当然 mod是素数

    lucas 就有如此应用

    上个例题吧

    HDOJ——5651

    这个题 果组合数死 可以用杨辉三角和lucas过

    ll com(ll n,ll m) //计算组合数C(n,m)
    {
        ll sum=1; //线性计算
        for(ll i=1,j=n;i<=m;i++,j--)
            sum=(sum*j)/i;
        return sum;
    } 
    超简陋的组合数代码

    杨辉三角AC代码

    #include<cstdio>
    #include<map>
    #include<vector>
    #include<stack>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<cstdlib> 
    #include<climits>
    #define PI acos(-1.0)
    #define INF 0x3fffffff
    using namespace std;
    typedef __int64 ll;
    typedef __int64 int64;
    const ll MOD=1e9+7;
    const int64 Mod=1e9+7;
    const double eps=1e-9;
    const int N=32768;
    const int MAXN=200000;
    typedef int rl; 
    inline void r(rl&num){
        num=0;rl f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
        num*=f;
    }    
    int c[1010][1010];
    char ch[1010];
    int a[27];
    int main(){
        for(int i=0;i<1010;i++)
        {
            c[i][i]=c[i][0]=1;
        }
        for(int i=0;i<1010;i++)
        {
            for(int j=1;j<=i;j++)
            {
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%Mod; 
            }
        }
        int T;
        r(T);
        while(T--){
            scanf("%s",ch);
            int len=strlen(ch);
            for(int i=0;i<len;i++)
            {
                 a[ch[i]-'a']++;
            }
            int sum=0,s=0;
            for(int i=0;i<26;i++)
            {
                if(a[i]&1){
                    a[i]--;
                    sum++;
                }
                if(a[i]){
                    s++;
                }
            }
            if(sum>1){
                printf("0
    ");
            }
            else{
                if(s==0||s==1){
                    printf("1
    ");
                }
                else{
                    len=(len-sum)/2;
                    int64 x=1;
                    for(int i=0;i<26&&s>1;i++)
                    {
                        if(a[i]){
                            s--;
                            x*=c[len][a[i]/2];
                            len-=a[i]/2;
                            x%=Mod;
                        } 
                    }
                    printf("%I64d
    ",x);
                }
            }
            memset(a,0,sizeof(a));
        }
        return 0;
    }
    杨辉三角代码

    改动一点 但是死了

    #include<cstdio>
    #include<map>
    #include<vector>
    #include<stack>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<cstdlib> 
    #include<climits>
    #define PI acos(-1.0)
    #define INF 0x3fffffff
    using namespace std;
    typedef __int64 ll;
    typedef __int64 int64;
    const ll MOD=1e9+7;
    const int64 Mod=1e9+7;
    const double eps=1e-9;
    const int N=1e3+10;
    const int MAXN=200000;
    typedef int rl; 
    inline void r(rl&num){
        num=0;rl f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
        num*=f;
    } 
    ll f[N];
    void init(int p) {                 //f[n] = n!
        f[0] = 1;
        for (int i=1; i<=p; ++i) f[i] = f[i-1] * i % p;
    }
      
    ll pow_mod(ll a, ll x, int p)   {
        ll ret = 1;
        while (x)   {
            if (x & 1)  ret = ret * a % p;
            a = a * a % p;
            x >>= 1;
        }
        return ret;
    }
    ll Lucas(ll n, ll k, int p) {       //C (n, k) % p
         ll ret = 1;
         while (n && k) {
            ll nn = n % p, kk = k % p;
            if (nn < kk) return 0;                   //inv (f[kk]) = f[kk] ^ (p - 2) % p
            ret = ret * f[nn] * pow_mod (f[kk] * f[nn-kk] % p, p - 2, p) % p;
            n /= p, k /= p;
         }
         return ret;
    } 
    char ch[1010];
    int a[27];
    int main(){
        int T;
        init(N-1);
        r(T);
        while(T--){
            scanf("%s",ch);
            int len=strlen(ch);
            for(int i=0;i<len;i++)
            {
                 a[ch[i]-'a']++;
            }
            int sum=0,s=0;
            for(int i=0;i<26;i++)
            {
                if(a[i]&1){
                    a[i]--;
                    sum++;
                }
                if(a[i]){
                    s++;
                }
            }
            if(sum>1){
                printf("0
    ");
            }
            else{
                if(s==0||s==1){
                    printf("1
    ");
                }
                else{
                    len=(len-sum)/2;
                    int64 x=1;
                    for(int i=0;i<26&&s>1;i++)
                    {
                        if(a[i]){
                            s--;
                            x*=Lucas(len,a[i]/2,Mod);
                            len-=a[i]/2;
                            x%=Mod;
                        } 
                    }
                    printf("%I64d
    ",x);
                }
            }
            memset(a,0,sizeof(a));
        }
        return 0;
    }
    暂时不知道哪里wa

    问了利文学长后 改为

    #include<cstdio>
    #include<map>
    #include<vector>
    #include<stack>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<cstdlib> 
    #include<climits>
    #define PI acos(-1.0)
    #define INF 0x3fffffff
    using namespace std;
    typedef __int64 ll;
    typedef    __int64 LL;
    typedef __int64 int64;
    const ll MOD=1e9+7;
    const int64 Mod=1e9+7;
    const ll p=1e9+7;
    const double eps=1e-9;
    const int N=1e3+10;
    const int MAXN=200000;
    typedef int rl; 
    inline void r(rl&num){
        num=0;rl f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
        num*=f;
    } 
    LL quick_mod(LL a, LL b)  
    {  
        LL ans = 1;  
        a %= p;  
        while(b)  
        {  
            if(b & 1)  
            {  
                ans = ans * a % p;  
                b--;  
            }  
            b >>= 1;  
            a = a * a % p;  
        }  
        return ans;  
    }  
      
    LL C(LL n, LL m)  
    {  
        if(m > n) return 0;  
        LL ans = 1;  
        for(int i=1; i<=m; i++)  
        {  
            LL a = (n + i - m) % p;  
            LL b = i % p;  
            ans = ans * (a * quick_mod(b, p-2) % p) % p;  
        }  
        return ans;  
    }  
      
    LL Lucas(LL n, LL m)  
    {  
        if(m == 0) return 1;  
        return C(n % p, m % p) * Lucas(n / p, m / p) % p;  
    }  
    char ch[1010];
    int a[27];
    int main(){
        int T;
        r(T);
        while(T--){
            scanf("%s",ch);
            int len=strlen(ch);
            for(int i=0;i<len;i++)
            {
                 a[ch[i]-'a']++;
            }
            int sum=0,s=0;
            for(int i=0;i<26;i++)
            {
                if(a[i]&1){
                    a[i]--;
                    sum++;
                }
                if(a[i]){
                    s++;
                }
            }
            if(sum>1){
                printf("0
    ");
            }
            else{
                if(s==0||s==1){
                    printf("1
    ");
                }
                else{
                    len=(len-sum)/2;
                    int64 x=1;
                    for(int i=0;i<26&&s>1;i++)
                    {
                        if(a[i]){
                            s--;
                            x*=Lucas(len,a[i]/2);
                            len-=a[i]/2;
                            x%=Mod;
                        } 
                    }
                    printf("%I64d
    ",x);
                }
            }
            memset(a,0,sizeof(a));
        }
        return 0;
    }
    lucas AC代码

    换个思路问题 可以用 N!/a[0]!/..../a[25]! 乘逆元计算

  • 相关阅读:
    1063. Set Similarity
    A1047. Student List for Course
    A1039. Course List for Student
    最大公约数、素数、分数运算、超长整数计算总结
    A1024. Palindromic Number
    A1023. Have Fun with Numbers
    A1059. Prime Factors
    A1096. Consecutive Factors
    A1078. Hashing
    A1015. Reversible Primes
  • 原文地址:https://www.cnblogs.com/Geek-xiyang/p/5334841.html
Copyright © 2011-2022 走看看