卢卡斯定理
通常情况下:C(a,b) mod p=a!*inv[b!]*inv[(a-b)!] mod p
其中inv[x]代表x关于p的逆元 inv[x!]可以由inv[1]*inv[2]*...*inv[x]%mod得到所以本质上求inv[x!]得要求inv[x],可是求inv[x]的时候,求逆元得要求x和p互质,但是如果a很大那么b和a-b就有可能是p的倍数,这种情况下就不能求inv[b]和inv[a-b]了,遇到这种情况我们就要用卢卡斯定理:
递归计算当n/p和m/p都小于p时就可以结束了
int ksm(int x,int n,int p){
int ans=1;
while(n){
if(n%2==1){
ans=ans*x%p;
}
x=x*x%p;
n/=2;
}
return ans;
}
int comb(int a,int b,int p){
if(b>a){
return 0;
}
int ans=1;
for(int i=1,j=a;i<=b;i++,j--){
ans=ans*j%p;
ans=ans*ksm(i,p-2,p)%p;
}
return ans;
}
int lucas(int a,int b,int p){
if(a<p&&b<p){
return comb(a,b,p);
}
return comb(a%p,b%p,p)*lucas(a/p,b/p,p)%p;
}
卡特兰数
C(n)表示,从原点出发,每次向x或y轴正方向移动1单位,到达点(n,n),且在移动过程中不越过第一象限平分线的移动方案数。
则 :
容斥定理:
求n个元素的并集==n个元素相加-n个元素两两的交集+n个元素3个的交集...+(-1)^(n-1)*n个元素的交集
圆排列:
对于n个元素的圆有n!/n即(n-1)!种排列