您的位置:首页 > 其它

计算多项式的系数

2018-01-25 15:32 218 查看

题目简介

给定一个多项式 (ax+by)k(ax+by)k,计算多项式展开后 xnymxnym 项的系数。

Input

第 1 行:一个整数 T (1≤T≤100000)为问题数。

接下来共 T 行。每行 5 个整数,分别为 a,b,k,n,m,整数之间由一个空格分隔。

0≤k≤1,000,000,0≤n,m≤k,且 n+m=k,0≤a,b≤10^9。

Output

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)。

然后对应每个问题在一行中输出一个整数,表示所求的系数(这个系数可能很大,输出对 1000000007 取模后的值)。

说明

由于n,m过大不能直接预处理组合数;又因为p过大Lucas定理的递归形式在这里也不能直接使用。后来才发现原来只要预处理阶乘+快速幂+逆元求组合数就可以了。。。

#include <bits/stdc++.h>
#define p 1000000007
#define K 1000000

typedef long long ll;
ll a, b, k, n, m, fac[K+1];

void init()
{
fac[0] = 1;
for(int i = 1; i <= K; ++i)
fac[i] = fac[i-1]*i % p;
}

ll pow_mod(ll a, ll x)
{
ll ret = 1;
while (x) {
if (x & 1) ret = (ret * a) % p;
a = (a * a) % p;
x >>= 1;
}
return ret;
}

ll C(ll n, ll m)
{
if(m > n) return 0;
return fac
* pow_mod((fac[m]*fac[n-m])%p, p-2) % p;
}

int main()
{
int cas;
ll ans;
scanf("%d", &cas);
init();
for (int t = 0; t < cas; ++t) {
scanf("%lld%lld%lld%lld%lld", &a, &b, &k, &n, &m);
ans = pow_mod(a, n);
ans = (ans * pow_mod(b, m)) % p;
ans = (ans * C(k, m)) % p;
printf("case #%d:\n%lld\n", t, ans);
}
return 0;
}


顺便扔个Lucas模板(非原创)备用,n,m较大而P较小时可用:

#include<bits/stdc++.h>
#define P 10007
using namespace std;

typedef long long ll;

ll pow_mod(ll a, ll x, int p)
{
ll ret = 1;
while(x) {
if (x & 1) ret = ret * a % p;
a = a * a % p;
x >>= 1;
}
return ret;
}

ll comb(ll a, ll b, int p)
{
if (a < b) return 0;
if (a == b) return 1;
if (b > a - b) b = a - b;
ll ans = 1, ca = 1, cb = 1;
for (ll i = 0; i < b; ++i) {
ca = (ca * (a - i)) % p;
cb = (cb * (b - i)) % p;
}
ans = (ca * pow_mod(cb, p-2, p)) % p;
return ans;
}

ll lucas(ll n, ll m, int p)
{
ll ans = 1;
while(n && m && ans) {
ans = (ans * comb(n%p, m%p, p)) % p;
n /= p;
m /= p;
}
return ans;
}

int main()
{
int cas, k;
ll a, b, n, m;
cin >> cas;
for (int t = 0; t < cas; ++t) {
cin >> a >> b >> k >> n >> m;
printf("case #%d:\n", t);
if (n + m != k) cout << "0" << endl;
else {
ll ans = pow_mod(a, n, P);
ans = (ans * pow_mod(b, m, P)) % P;
ans = (ans * lucas(k, n, P)) % P;
cout << ans << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: