组合数公式:
我们需要求阶乘和逆元阶乘
我们就用1e9+7来求余吧
费马小定理
a^(p-1) ≡1 (mod p)
两边同除以a
a^(p-2) ≡1/a (mod p)
数论1/a 是inv(a)
应该写a^(p-2) ≡ inv(a) (mod p)
所以inv(a) = a^(p-2) (mod p)
这个用快速幂求一下,复杂度O(logn)
引用其他人写的一句话
除法求模不能类似乘法,对于(A/B)mod C,直接(A mod C)/ (B mod C)是错误的;找到B的逆元b(b=B^-1);求出(A*b)modC即可;
由费马小定理:B 关于 P 的逆元为 B^(p-2);
费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。所以,a^-1*a=1=a^(p-1),所以:a^-1=a^(p-2);
数学排列组合公式:C(n,m)= n!/(m!*(n-m)!)
/////////////////////////////////////////////////////////////////////////////////////////////////////
LL pow_mod(LL a, LL b, LL p){//a的b次方求余p /
LL ret = 1;
while(b){
if(b & 1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
return ret;
}
LL Fermat(LL a, LL p){//费马求a关于b的逆元
return pow_mod(a, p-2, p);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define LL long long
- #define G 1100000
- #define mod 1000003
- LL pri[G];
- LL ni[G],ans;
- LL pow(LL a,int b)
- {
- LL ans=1,base=a;
- while (b>0)
- {
- if (b%2==1)
- ans=(base*ans)%mod;
- base=(base*base)%mod;
- b/=2;
- }
- return ans;
- }
- void s() //打表
- {
- pri[0]=1;
- ni[0]=1;
- for (int i=1;i<G ;i++)
- {
- pri[i]=pri[i-1]*i%mod; //N!
- ni[i]=pow(pri[i],mod-2);
- }
- }
- int main()
- {
- s();
- int t,n,b,k=1;
- scanf("%d",&t);
- while (t--)
- {
- scanf("%d%d",&n,&b);
- ans=((pri[n]*ni[b]%mod)*ni[n-b])%mod; // C(n,m)= n!/(m!*(n-m)!)//就是上面公式的表示
- printf("Case %d: %lld\n",k++,ans);
- }
- return 0;
- }
2019.2.22
一只现在很饱的猴猴
原文地址:https://www.cnblogs.com/pipihoudewo/p/10420625.html