题解:P1313 [NOIP2011 提高组] 计算系数
GoldenSTEVE7 · · 题解
题意
求多项式
分析
本题的求解需要用到一个定理:二项式定理。
该定理的证明不会的可以去百度一下,在这里我就不详细证明了。
我们观察一下原式,发现这不就是二项式定理的样子吗,直接硬拆!
我们要找的
那么接下来问题又来了,
这时候我们需要用到组合数的定义式:
但是由于计算中包含了除法,所以我们还需要通过逆元进行计算。
下面是科普时间(学习过逆元的大佬可以直接跳过):
我们看下面一个式子:
是不是很有道理。
那么我们在取模的时候,也是可以这么干的。
这其中
那我们可以发现,两个正整数
那么我们就可以回到上面的那个式子啦!
所以
那么问题又又来了,咋求逆元啊?
这就不得不再提到一个定理了——费马小定理:
如果
我们的目标是通过这个定理去求
接下来不要眨眼,由于
吔,这右边不就是
所以我们就得到了结论:
好的以上是对于逆元的科普。
回到原题,那么这个可爱(可恶)的
最后将其与
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int p = 10007;
ll fpow(ll a, ll b) {
ll ret = 1;
for(; b; b >>= 1) {
if(b & 1) ret = ret*a%p;
a = a*a%p;
}
return ret;
}//快速幂
ll inv(ll x) {return fpow(x,10005);}//求逆元
int main() {
int a, b, k, n, m;
cin >> a >> b >> k >> n >> m;
ll N = 1, KN = 1, K = 1;
ll ans = fpow(a, n) * fpow(b, m); ans %= p;
if(n > m) n = m;
for(int i = 1; i <= n; i++) N *= i, N %= p;
for(int i = 1; i <= k; i++) K *= i, K %= p;
for(int i = 1; i <= k-n; i++) KN *= i, KN %= p;
//分别求出n!,k!,(k-n)!
ans = ans * K * inv(N*KN%p) % p;
cout << ans;
return 0;
}