题目链接:http://codeforces.com/problemset/problem/893/E
题意:给出Q次询问,每次询问给出X,Y, 求有多少种长度为Y的序列满足其相乘得到X。
如X=4,Y= 2可由以下6种得到:
- { - 4, - 1};
- { - 2, - 2};
- { - 1, - 4};
- {1, 4};
- {2, 2};
- {4, 1}.
首先将X用唯一分解定理分解X = P1^a1 * P2^a2 * .....Pk^ak,记录下每个每个素数的指数,然后就转换成k个互相独立的事件,假设当前处理的为Pi^ai,就等价于现在有Y个盒子,有ai个不同的球往Y个盒子里面放,盒子允许为空的操作,经典的组合问题.C(ai, y+ai-1),预处理下阶乘,在每次求下逆元即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 7;
const ll mod = 1e9 + 7;
int q;
ll a[30], x, y, fac[N], two[N];
ll qmod(ll n, ll k)
{
ll ans = 1;
while(k) {
if(k&1) ans = ans * n % mod;
k>>=1;
n = n * n % mod;
}
return ans % mod;
}
ll inv(ll n)
{
return qmod(n, mod-2);
}
ll C(ll m, ll n)
{
ll M = fac[m];
ll NM = fac[n]*fac[m-n]%mod;
NM = M*inv(NM)%mod;
return NM;
}
void init()
{
fac[0] = 1;
two[0] = 1;
for(int i = 1;i < N;i ++) {
two[i] = two[i - 1] * 2LL % mod;
fac[i] = fac[i - 1] * i % mod;
}
}
int main()
{
init();
scanf("%d",&q);
while(q --) {
memset(a, 0, sizeof(a));
int tot = 0;
ll ans = 1;
scanf("%lld%lld",&x,&y);
for(int i = 2;i * i <= x;i ++) {
if(x % i == 0) {
tot ++;
while(x % i == 0) {
a[tot] ++; x /= i;
}
}
}
if(x!=1) a[++tot] = 1;
for(int i = 1;i <= tot;i ++) ans = ans*C(y+a[i]-1,a[i]) % mod;
ans = ans * two[y-1] % mod;
printf("%lld\n",ans);
}
return 0;
}