51Nod1120

思路

为什么用到了Lucas定理?

因为n很大,但是mod却只有10007这么大。

参考公式:https://blog.csdn.net/doyouseeman/article/details/53447279?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.channel_param

参考博客:

  1. https://www.cnblogs.com/Serene-shixinyi/p/8073742.html

  2. https://www.cnblogs.com/alan-W/p/9034617.html

Lucas定理

参考博客:

  1. https://zhuanlan.zhihu.com/p/116698264

  2. https://blog.csdn.net/Jokercold/article/details/77261786?locationNum=9 fps=1

求组合,并且数据比较大,需要用到 Lucas 定理。

适用领域范围:大组合数求模。

Lucas定理是用来求: (C(n,m)mod p)(p) 为素数的值。

卡特兰数

参考博客:
https://blog.csdn.net/weixin_30814319/article/details/97990934?utm_medium=distribute.pc_relevant.none-task-blog-title-9&spm=1001.2101.3001.4242

对于求上三角和下三角的方案数,基本跟卡特兰数有关。

AC代码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>

using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f

const ll mod=10007;
ll niyuan[10010];

ll ksm(ll x,int nn)  // **快速幂写错了
{
    ll res=1;
    while(nn)
    {
        if(nn&1)
            res=res*x%mod;
        x=x*x%mod;
        nn>>=1;
    }
    return res;
}

ll C(ll m,ll n) // 求组合
{
    if(n>m) return 0;
    ll x=1;
    for(int i=1;i<=n;i++)
        x=x*(m-i+1)%mod*niyuan[i]%mod;
    return x;
}

ll Lucas(ll n,ll m) //Lucas定理
{
    if(m==0) return 1;
    return Lucas(n/mod,m/mod)%mod*C(n%mod,m%mod)%mod;
}

ll w(ll n)
{
    ll q=Lucas(2*n,n)%mod;
    ll x=ksm(n+1,mod-2);
    q=(q%mod*x%mod)%mod;
    return q*2%mod;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=mod;i++)
        niyuan[i]=ksm(i,mod-2); //预处理求逆元
    ll ans=w(n-1);
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/OFSHK/p/13821393.html