• 大组合数取模——fzu 2020(可做模板)


    http://blog.csdn.net/swm8023/article/details/6525980

    比较好的资料

    求C(10,3,107)

    第一步: 10/3

    第二步: *9/2

    第三步:*8/1

    如第一步里会出现除不下时的情况,用中国剩余定理做

    View Code
    #include<stdio.h>

    long long min(long long a,long long b)
    {
    if(a>b)return b;
    else return a;
    }

    long long ext_gcd(long long a,long long b,long long &x,long long &y)
    {
    if(b==0){x=1,y=0;return a;}
    long long res=ext_gcd(b,a%b,y,x);
    y-=a/b*x;
    return res;
    }

    long long retx(long long a,long long b,long long n)
    {
    long long res,x,y,t;
    res=ext_gcd(a,b,x,y);
    if(n%res==0)
    {
    x=x*n/res;
    t=b/res;
    if(t<0)t=-t;
    x=(x%t+t)%t;
    return x;
    }
    return -1;
    }

    long long Cfun(long long n,long long m,long long p)
    {
    long long up=n,all=1,i;
    long long down=m;
    for(i=1;i<=m;i++)
    {
    all=all*up;
    all=all%p;

    if(all%down==0)
    all=all/down;
    else
    all=retx(down,p,all);
    down--;
    up--;
    }
    return all;
    }

    int main()
    {
    long long n,m,p,t,i;
    scanf("%lld",&t);
    while(t--)
    {
    scanf("%lld%lld%lld",&n,&m,&p);
    m=min(m,n-m);
    printf("%lld\n",Cfun(n,m,p));
    }
    }


    lucas定理过的,小数据量时速度不明显

    View Code
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int pow_mod(int a,int n,int p)
    {
    int ans=1,t=a;
    while(n)
    {
    if(n&1)
    ans=(long long)ans*t%p;
    t=(long long)t*t%p;
    n>>=1;
    }
    return ans;
    }
    int cal(int n,int m,long p)
    {
    if(m>n-m) m=n-m;
    int ans=1;
    for(int i=1;i<=m;i++)
    {
    ans=(long long)ans*(n-i+1)%p;
    int a=pow_mod(i,p-2,p);
    ans=(long long)ans*a%p;
    }
    return ans;
    }

    int com_mod(int n,int m,long p)
    {
    if(n<m)return 0;
    return cal(n,m,p);
    }

    int lucas(int n,int m,long p)
    {
    int r=1;
    while(n&&m&&r)
    {
    r=(long long)r*com_mod(n%p,m%p,p)%p;
    n/=p;
    m/=p;
    }
    return r;
    }

    int main()
    {
    int t;
    scanf("%d",&t);
    while(t--)
    {
    int n,m,p;
    scanf("%d%d%d",&n,&m,&p);
    printf("%d\n",lucas(n,m,p));
    }
    }



  • 相关阅读:
    拦截器接口(IActionFilter,IExceptionFilter,IResultFilter,IAuthorizationFilter)
    Linq学习
    keycode值大全
    C#使用Cookie方法
    领域驱动设计学习
    mvc3 razor语法学习
    O/R Mapping 阻抗失衡
    文档格式批量转换(doc,txt,pdf等)
    统计sql语句
    如何确定文件编码格式的方法??
  • 原文地址:https://www.cnblogs.com/huhuuu/p/2319245.html
Copyright © 2020-2023  润新知