组合&排列

打包版

诡异打包

费马小

struct Combinatorics
{
	long long f[maxn],g[maxn];
	long long ksm(long long x,long long y,long long mo)
	{
		long long cnt=1;
		while(y)
		{
			if (y&1) cnt=(cnt*x)%mo;
			x=(x*x)%mo;
			y>>=1;
		}
		return cnt;
	}
	long long NY(long long a,long long p) {return ksm(a,p-2,p);}
	void getfg(long long n)
	{
		f[0]=g[0]=1;
		for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
	}
	long long getC(long long x,long long y) {return ((f[x]*g[x-y])%p*g[y])%p;}
	long long d[maxn];
	void getD(long long n)
	{
		d[1]=0,d[2]=1;
		for (long long i=3;i<=n;i++) (d[i]=(i-1)*(d[i-1]+d[i-2])%p+p)%=p;
	}
}c;

lucas

struct C
{
	long long f[maxn],g[maxn];
	long long ksm(long long x,long long y,long long mo)
	{
		long long cnt=1;
		while(y)
		{
			if (y&1) cnt=(cnt*x)%mo;
			x=(x*x)%mo;
			y>>=1;
		}
		return cnt;
	}
	long long NY(long long a,long long p) {return ksm(a,p-2,p);}
	void getfg(long long n)
	{
		f[0]=g[0]=1;
		for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
	}
	long long getC(long long x,long long y) {if (x<y) return 0;return (f[x]*g[x-y]%p*g[y])%p;}
	long long lucas(long long x,long long y)
	{
		if (y == 0) return 1;
		return (getC(x%p,y%p)*lucas(x/p,y/p))%p;
	}
}c;

乘法逆元法

long long f[10010],g[10010];
long long ksm(long long x,long long y,long long mo)
{
	long long cnt=1;
	while(y)
	{
		if (y&1) cnt=(cnt*x)%mo;
		x=(x*x)%mo;
		y>>=1;
	}
	return cnt;
}
long long NY(long long a,long long p) {return ksm(a,p-2,p);}
void getfg(long long n)
{
	f[0]=g[0]=1;
	for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
}
long long getC(long long x,long long y) {return ((f[x]*g[x-y])%p*g[y])%p;}
long long getA(long long x,int y) {return f[x]*g[x-y]%p;}

lucas

long long f[10010],g[10010];
long long ksm(long long x,long long y,long long mo)
{
	long long cnt=1;
	while(y)
	{
		if (y&1) cnt=(cnt*x)%mo;
		x=(x*x)%mo;
		y>>=1;
	}
	return cnt;
}
long long NY(long long a,long long p) {return ksm(a,p-2,p);}
void getfg(long long n)
{
	f[0]=g[0]=1;
	for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
}
long long getC(long long x,long long y) {if (x<y) return 0;return (f[x]*g[x-y]%p*g[y])%p;}
long long lucas(long long x,long long y)
{
	if (y == 0) return 1;
	return (getC(x%p,y%p)*lucas(x/p,y/p))%p;
}

推推推

long long getA(long long x,long long y)
{
	long long res=1;
	for (int i=x-y+1;i<=x;i++) res*=i;
	return res;
}
long long getC(long long x,long long y)
{
	long long res=getA(x,y);
	for (int i=1;i<=y;i++) res/=i;
	return res;
}

杨辉三角递推法

int c[maxn][maxn];
void getC(int n)
{
	for (int i=0;i<n;i++)
	{
		for (int j=1;j<=i;j++)
		{
			if (!j) c[i][j]=1;
			else c[i][j]=(c[i-1][j]+c[i-1][j-1])%p;
		}
	}
}

动态开点杨辉三角

c[2][maxn]

c[0][0]=c[1][0]=c[1][1]=1;
for (int i=2;i<=n;i++)
{
	for (int j=1;j<=i;j++) c[i&1][j]=(c[(i&1)^1][j-1]+c[(i&1)^1][j])%p;
	for (int j=0;j<i;j++) printf("%lld ",c[(i&1)^1][j]);
	printf("\n");
}

exgcd算逆元

long long f[maxn],g[maxn];
long long ksm(long long x,long long y,long long mo)
{
	long long cnt=1;
	while(y)
	{
		if (y&1) cnt=(cnt*x)%mo;
		x=(x*x)%mo;
		y>>=1;
	}
	return cnt;
}
long long x,y;
long long exgcd(long long a,long long b,long long &x,long long &y)
{
	if (b == 0)
	{
		x=1;
		y=0;
		return a;
	}
	long long res=exgcd(b,a%b,x,y);
	long long t=x;
	x=y;
	y=t-a/b*y;
	return res;
}
long long NY(long long a,long long p)
{
	long long g=exgcd(a,p,x,y);
	x=(x%p+p)%p;
	return x;
}
void getfg(long long n)
{
	f[0]=g[0]=1;
	for (long long i=1;i<=n;i++) (f[i]=i*f[i-1])%=p,g[i]=NY(f[i],p);
}
long long getC(long long x,long long y) {return ((f[x]*g[x-y])%p*g[y])%p;}
long long getA(long long x,int y) {return f[x]*g[x-y]%p;}
posted @ 2026-06-30 12:15  msjing  阅读(7)  评论(0)    收藏  举报