• 卢卡斯定理


    问题求解(C_{n+m}^m pmod{p})的值

    当然可以不用卢卡斯定理。

    [C_{n+m}^m=frac{(n+m)!}{n!*m!} ]

    (color{Orange}{问题似乎很简单,分子暴力乘,分母同理求个逆元ok了。})

    (color{Green}{错错错!!!})

    (当分母含有x个p因子,分子含有y个p因子。)

    (color{Blue}{若x==y,那么显然C_{n+m}^m pmod{p}不为0})

    (color{Purple}{但我们是分别对分子分母计算求余的,一遇到含p因子时就被模成0了})

    (color{#000}{正确的做法是每次都除去p因子,并且统计因子个数})

    (分子分母p因子个数相同,算出的答案就是答案。不同,答案就是0.)

    我的代码

    当然也可以用卢卡斯定理。

    但是因为我还没看懂的原因,先留坑....

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll maxn=1e5+9;
    ll inv[maxn],fac[maxn],n,m;
    void init()
    {
    	fac[0]=1;
    	for(ll i=1;i<=100000;i++)	fac[i]=fac[i-1]*i%p;//求阶乘 
    	inv[0]=inv[1]=1;
    	for(int i=2;i<=10000;i++)	inv[i]=(p-p/i)*inv[p%i]%p;//递推逆元 
    	for(int i=2;i<=10000;i++)	inv[i]=inv[i-1]*inv[i]%p;//这步在干嘛我也不懂 
    }
    ll lucas(ll x,ll y)
    {
    	if(x<y)	return 0;
    	else if(x<2)	return fac[x]*inv[y]*inv[x-y]%p;
    	else	return lucas(x/p,y/p)*lucas(x%p,y%p)%p;
    }
    int main()
    {
    	init();
    	cin>>n>>m;
    	cout<<lucas(n,m);		
    }
    
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a[100009],n,m,p;
    ll qpow(ll a,ll n)
    {
    	ll ans=1;
    	while(n)
    	{
    		if(n&1)	ans=ans*a%p;
    		n>>=1;
    		a=a*a%p;
    	}
    	return ans;
    }
    ll C(ll n,ll m)
    {
    	if(m>n)	return 0;
    	return a[n]*qpow(a[m],p-2)%p*qpow(a[n-m],p-2)%p;
    }
    ll Lucas(ll n,ll m)
    {
    	if(!m)	return 1;
    	return C(n%p,m%p)*(Lucas(n/p,m/p))%p;	
    } 
    int main()
    {
    	cin>>n>>m>>p;
    	a[0]=1;
    	for(ll i=1;i<=p;i++)	a[i]=(a[i-1]*i)%p;
    	cout<<Lucas(n+m,n)<<endl;
    }
    
  • 相关阅读:
    js—初始的二维数组是一个,3行4列的数组。将其转换为4行3列的二维数组
    js_求1—10000的完数
    JS——输入一个日期判断该日期为当年的第几天
    JS——打印倒三角和正三角
    Java内存机制和内存地址
    deepin下搭建基于github和hexo的个人博客
    URL and URI 的 比较
    Cannot use this in a static context
    java项目获取文件路径总结
    利用exe4j制作exe文件
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12744810.html
Copyright © 2020-2023  润新知