hdu-5668- Circle 逆元+卡特兰数知识模板

本文介绍模运算中逆元的概念及两种求解方法,包括扩展欧几里得算法和特殊情况下的递推公式,并给出卡特兰数的计算实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(a/b)%mod = (a%mod*(b的逆元))%mod
逆元求法:

  //1:     通用扩展欧几里得;
long long extend_gcd(long long a,long long b,long long &x,long long &y)  
{  
    if(a==0&&b==0) return -1;//无最大公约数  
    if(b==0){x=1;y=0;return a;}  
    long long d=extend_gcd(b,a%b,y,x);  
    y-=a/b*x;  
    return d;  
}  
//*********求逆元素*******************  
//ax = 1(mod n)  
long long mod_reverse(long long a,long long n)  
{  
    long long x,y;  
    long long d=extend_gcd(a,n,x,y);  
    if(d==1) return (x%n+n)%n;  
    else return -1;  
}  
 //2.mod 为质数特殊情况
 //第一种 递推 inv[i] = inv[mod%i]*(mod-mod/i)%mod;
 //第二种 费马小定理a^(mod-1)%mod = 1 a关于m的逆元a^mod-2;

卡特兰数 h(n) = c(n,2n)/(n+1) = (4*n-2)*h(n-1)/(n+1);
当遇到组合数和序号匹配或出栈次序相似的问题往这方面想

#include<cstdio>
#define mod 1000000007
#define LL long long
LL t,cat[500005],n,ans,c[1000005],inv[1000005];
void init()
{
     cat[0] = 1;
    inv[1] = 1;
    for (int i = 2; i <= 1000000; i++)
        inv[i] = inv[mod%i]*(mod-mod/i)%mod;
     for(LL i=1;i<=500005;i++)
         cat[i] = (cat[i-1]*(4*i-2))%mod*inv[i+1]%mod;
}
void gao()
{
    c[0] = 1;
    for(LL i=1;i<=n;i++)
        c[i] = (c[i-1]*(n-i+1))%mod*inv[i]%mod;
}
int main()
{
    init();
    scanf("%I64d",&t);
    while(t--)
    {
       scanf("%I64d",&n);
       gao();
       ans = 0;
       for(LL i=0;i*2<=n;i++)
          ans = (ans+c[i*2]*cat[i])%mod;
       printf("%I64d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值