题意:把一个数x,分成长度为y的数组的乘积,求有几种方案
思路:题目的本质就是将x的质因子进行划分,求有几种组合方案。可以这么想,对于他的每一种质因子分配到y组,且允许为空,其实就是允许有空的隔板法,假如当前数对于质因子5,它的次数是4次,分到长度为y的数组,那么组合数是
C
(
5
−
1
+
y
,
y
−
1
)
C(5-1+y,y-1)
C(5−1+y,y−1)关于隔板法。最后考虑符号的问题,发现只能取偶数个符号也就是
C
(
y
,
0
)
+
C
(
y
,
2
)
.
.
.
.
.
C(y,0)+C(y,2).....
C(y,0)+C(y,2).....,也就是
2
y
/
2
2^y/2
2y/2。
const int N = 2e6+5;
int t;
ll p[N+1], cnt;
bool vis[N+1];
ll fact[N], infact[N];
void x_x()
{
f(i, 2, N)
{
if (!vis[i])p[++cnt] = i;
for (int j = 1;p[j] <= N / i;j++)
{
vis[p[j] * i] = true;
if (i%p[j] == 0)break;
}
}
fact[0] = infact[0] = 1;
f(i, 1, N-1)fact[i] = fact[i - 1] * i%mod;
infact[N - 1] = inv(fact[N - 1], mod);
ff(i, N - 2, 1)infact[i] = infact[i + 1] * (i + 1) % mod;
}
ll C(ll a, ll b)
{
return fact[a] * infact[b] % mod*infact[a - b] % mod;
}
int main()
{
//freopen("in.txt", "r", stdin);
cin >> t;
x_x();
while (t--)
{
ll x, y;
scanf("%lld%lld", &x, &y);
ll ans = 1;
for (ll i = 1;p[i] * p[i] <= x && i <= cnt;i++)
{
if (x%p[i] == 0)
{
int cot = 0;
while (x%p[i] == 0)cot++, x /= p[i];
//允许空元素的隔板法C(n+m-1,m-1)两倍。。。
ans = ans * C(cot + y - 1, y - 1) % mod;
}
}
if (x > 1)ans = ans * C(y, y - 1) % mod;
//关于负数符号
ans = ans * quickmod(2, y - 1,mod) % mod;
cout << ans << endl;
}
return 0;
}