社区讨论

lucas板子求调

学术版参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lyx3gqpa
此快照首次捕获于
2024/07/22 22:40
2 年前
此快照最后确认于
2024/07/23 08:56
2 年前
查看原帖
这是我的lucas板子,我发现当p很大的时候会爆掉(准确来说是遇到了一道p=1e9+7的题),这咋改啊?有无更好的板子推荐
CPP
/*卢卡斯定理*/
//背景:求C(n,m)%p,p是质数
//公式:结论1 -> C(p,x)%p=0;
//     结论2 -> [(1+x)^p]%p=1+x^p
//     结论3 -> 卢卡斯:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
//注意:这里p是质数,如果不是质数,移步扩展卢卡斯

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int f[N],g[N];
ll ksm(ll a,ll b,ll p)
{
	ll ans=1,base=a;
	while(b)
	{
		if(b&1)ans*=base,ans%=p;
		base*=base,base%=p;b>>=1;
	}
	return ans;
}
void init(int p)
{
	f[0]=g[0]=1;
	for(int i=1;i<=p;i++)
	{
		f[i]=f[i-1]*i%p;
		g[i]=g[i-1]*ksm(i,p-2,p)%p;
	}
}
ll getC(ll n,ll m,ll p)
{
	if(n<m)return 0;
	return f[n]*g[m]*g[n-m]%p;
}
ll lucas(ll n,ll m,ll p)
{
	if(m==0)return 1;
	return lucas(n/p,m/p,p)*getC(n%p,m%p,p)%p;
}
void solve()
{
	ll n,m,p;
	init(p);
	cin>>n>>m>>p;
	cout<<lucas(n,m,p);
}

回复

3 条回复,欢迎继续交流。

正在加载回复...