• *HDU3398 数学


    String

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2552    Accepted Submission(s): 755


    Problem Description
    Recently, lxhgww received a task : to generate strings contain '0's and '1's only, in which '0' appears exactly m times, '1' appears exactly n times. Also, any prefix string of it must satisfy the situation that the number of 1's can not be smaller than the number of 0's . But he can't calculate the number of satisfied strings. Can you help him?
     
    Input
    T(T<=100) in the first line is the case number.
    Each case contains two numbers n and m( 1 <= m <= n <= 1000000 ).
     
    Output
    Output the number of satisfied strings % 20100501.
     
    Sample Input
    1
    2 2
     
    Sample Output
    2
     
    Author
    lxhgww
     
    Source
     
    题意:
    0,1组成的串,前缀中1始终多于0.
    求卡特兰数但是数据是1000000;
    代码:
    //C(n+m,n)-C(n+m,n+1)=(n+m)!*(n+1-m)/m!*(n+1)!;
    //卡特兰数,数据太大。n个1,m个0,从(0,0)出发可以将1看作是向上走,0看作是向右走,这样合法的路径必定在直线y=x-1上方且不与他相交
    //做(0,0)关于y=x-1的对称点(1,-1),从(1,-1)出发到终点(m,n)的路径必定与直线相交,将这条路径关于y=x-1对称过去就是从(0,0)
    //到终点(n,m)不合法的情况。用总的减去就行
    //求n,n!质因数模板
    #include<bitsstdc++.h>
    using namespace std;
    typedef long long ll;
    #define mod 20100501
    #define maxm 2000006
    #define maxn 1000006
    int p[maxn];
    int prime[maxn],res,num;
    bool is_prime[maxm];
    void get_prime()         //得到素数表
    {
        prime[0]=2;
        res=1;
        for(int i=3;i<maxm;i+=2)
            if(!is_prime[i])
            {
                for(int j=i;j<maxm;j+=i)
                    is_prime[j]=1;
                prime[res++]=i;
            }
    }
    void divide1(int x)   //分解x的质因数
    {
        int cnt=0;
        while(x>1)
        {
            while(x%prime[cnt]==0)
            {
                p[cnt]++;
                x/=prime[cnt];
            }
            cnt++;
        }
        num=max(num,cnt);
    }
    void divide2(int x,bool flag)  //分解x!的质因数,flag判断是分子还是分母
    {
        int cnt=0;
        while(prime[cnt]<=x)
        {
            int tem=x;
            while(tem)
            {
                if(flag)
                p[cnt]+=tem/prime[cnt];
                else p[cnt]-=tem/prime[cnt];
                tem/=prime[cnt];
            }
            cnt++;
        }
        num=max(num,cnt);
    }
    ll make(ll x,ll y)   //x,y不知为何用int就不行,得到x^y。
    {
        ll ans=1;
        x%=mod;
        while(y)      //很巧妙
        {
            if(y&1)
            ans=(ans*x)%mod;
            x=(x*x)%mod;
            y/=2;
        }
        return ans;
    }
    ll get_ans()
    {
        ll ans=1;
        for(int i=0;i<=num;i++)
        {
            if(p[i])
            ans=make(prime[i],p[i])*ans%mod;
        }
        return ans;
    }
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        get_prime();
        while(t--)
        {
            num=0;
            memset(p,0,sizeof(p));
            scanf("%d%d",&n,&m);
            divide1(n+1-m);
            divide2(n+m,1);
            divide2(m,0);
            divide2(n+1,0);
            ll ans=get_ans();
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    第11组 团队Git现场编程实战
    团队项目-需求分析报告
    团队项目-选题报告
    第10组 Alpha事后诸葛亮
    第10组 Alpha冲刺(6/6)
    第10组 Alpha冲刺(5/6)
    第10组 Alpha冲刺(4/6)
    第10组 Alpha冲刺(3/6)
    第10组 Alpha冲刺(2/6)
    第10组 Alpha冲刺(1/6)
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/6107772.html
Copyright © 2020-2023  润新知