ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

用到了卡特兰数的性质,还有高精度压位,筛法找素数

2020-02-03 12:55:23  阅读:263  来源: 互联网

标签:节车厢 筛法 int 质数 压位 primes include 卡特兰


一列火车n节车厢,依次编号为1,2,3,…,n。

每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种。

输入格式
输入一个整数n,代表火车的车厢数。

输出格式
输出一个整数s表示n节车厢出栈的可能排列方式数量。

数据范围
1≤n≤60000
输入样例:
3
输出样例:
5

这道题的本质是卡特兰数

卡特兰数介绍(引用math73)

筛法求素数

最重要的是如何求解组合数,压位思想,还有组合数C(2n)(n)这个式子展开以后,用上下同时除以连续的质数的方法,将答案一点一点凑出来,而不是每次都是很长的数去除以一个数,这样降低了运行的时间。

    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int N=120010;
    int powers[N];//每个质数的次数
    int primes[N],cnt;/质数表2~2*n内的质数
    bool st[N];//用来储存这个数是不是质数
    typedef long long ll;
    void get_primes(int n)//筛法判断是不是质数
    {
        for(int i=2;i<=n;i++)
        if(!st[i])
        {
            primes[cnt++]=i;
            for(int j=i*2;j<=n;j+=i)
            st[j]=true;
        }
    }
    int get(int n,int p)//n的阶乘里有多少个因子p
    {
        ll s=0;
        while(n)
        {
            s+=n/p;
            n/=p;
        }
        return s;
    }
    void multi(vector<ll>&a,int b)//压位高精度运算
    {
        int t=0;
        for(int i=0;i<a.size();i++)
        {
            a[i]=a[i]*b+t;
            t=a[i]/100000000;
            a[i]%=100000000;
        }
        while(t)
        {
            a.push_back(t%100000000);
            t/=100000000;
        }
    }
    void out(vector<ll >&a)//输出
    {
        printf("%lld",a.back());
        for(int i=a.size()-2;i>=0;i--)
        printf("%08lld",a[i]);
        cout<<endl;
    }
    
    int main()
    {
        int n;
        cin>>n;
        get_primes(n*2);
        for(int i=0;i<cnt;i++)//分别求一下质数的次数
        {
            int p=primes[i];
            powers[p]=get(n*2,p)-get(n,p)*2;//(C2n n)是2n的阶乘除以(n的阶乘*n的阶乘),所以乘2
        }
        int k=n+1;//分解质因数
        for(int i=0;i<cnt&&primes[i]<=k;i++)
        {
            int p=primes[i],s=0;
            while(k%p==0)
            {
                s++;
                k/=p;
            }
            powers[p]-=s;
        }
        vector<ll>res;
        res.push_back(1);
            for(int i=2;i<=n*2;i++)
               for(int j=0;j<powers[i];j++)
                multi(res,i);
               out(res);
              return 0;
            
        }
    
    
    
    
    这个代码又是yxc大佬的源代码基础上写的注释,我还是太菜了。QAQ
    

标签:节车厢,筛法,int,质数,压位,primes,include,卡特兰
来源: https://www.cnblogs.com/arbor-one/p/12255202.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有