拓展卢卡斯定理 / exlucas

恶心东西爬、、、

我们要求解一个 (nm)modMM 是不太大的正整数,n,m 是可能比较大的正整数。

首先我们分解 M=i=1kpixi,我们对于每一个 i[1,k] 求出 (nm)modpixi,然后就会组成一个方程组,Ans(nm)(modp)ixi,因为模数显然互质,所以此时的 Ans 可以通过 CRT 求解。

问题是怎么求这个 (nm)modpk 呢,我们知道有 amodp 意义下有逆元的充要条件是 ap,这个地方就显得不一定有逆元了,不能直接求解,我们考虑变形:

(nm)n!m!(nm)!n!pxm!py(nm)!pzpxyz(modpk)

然后求解 n!px(modpk),这个 x 尽量往大了取,先挑出 p 的倍数直接做。

n!pxpnp(np!)ipi=1ni(modpk)

后面那一段其实是有一个长度为 pk 的循环节的,手玩可得,好像是一个威尔逊定理的推论,所以我们可以拆开写 >w<

n!pxpnp(np!)(ipi=1pki)npk(ip,i=pknpkni)(modpk)

写成递归的函数形式,那么 f(n)n!px(modp),有下柿:

f(n)=f(np)(ipi=1pki)npk(ip,i=pknpkni)(modpk)

直接递归暴力做就行了谢谢喵,放回去原式,发现 n!pxm!py(nm)!pzpxyz 前面的分数部分可以做了,那么还差一个 pxyz 的指数,这个东西显然是 f(n) 中省去的 pnp 的指数部分,可以直接累加这一部分。

然后终于他妈的做完了 /lh

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

int exgcd(int a,int b,int &x,int &y) {
    if(!b) return y=0, x=1, a;
    int ans=exgcd(b,a%b,y,x);
    return y-=a/b*x, ans;
}

int inv(int a,int p) {
	int x, y; exgcd(a,p,x,y);
    return (x%p+p)%p;
}

int ksm(int a,int b,int p) {
	int res=1%p;
	for( ; b; b>>=1) {
		if(b&1) res=res*a%p;
		a=a*a%p;
	}
	return res;
}

int fac(int n,int pi,int pk) {
	if(!n) return 1;
	int res=1;
	up(i,2,pk) if(i%pi) res=res*i%pk;
	res=ksm(res,n/pk,pk);
	up(i,2,n%pk) if(i%pi) res=res*i%pk;
	return res*fac(n/pi,pi,pk)%pk;
}

int C(int n,int m,int pi,int pk) {
	int above=fac(n,pi,pk), l=fac(m,pi,pk), r=fac(n-m,pi,pk), k=0;
	for(int i=n; i; i/=pi) k+=i/pi;
	for(int i=m; i; i/=pi) k-=i/pi;
	for(int i=n-m; i; i/=pi) k-=i/pi;
	return above*inv(l,pk)%pk*inv(r,pk)%pk*ksm(pi,k,pk)%pk;
}

int exlucas(int n,int m,int p) {
	int ans=0, x=p, t=sqrt(x);
	up(i,2,t) if(x%i==0) {
		int mul=1;
		while(x%i==0) x/=i, mul*=i;
		ans=(ans+C(n,m,i,mul)*(p/mul)%p*inv(p/mul,mul)%p)%p;
	}
	if(x>1) ans=(ans+C(n,m,x,x)*(p/x)%p*inv(p/x,x)%p)%p;
	return ans; 
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n, m, p;
	cin >> n >> m >> p;
	cout << exlucas(n,m,p); 
	return 0;
}
posted @   Hypoxia571  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示