E. Counting Arrays
time limit per test 3 seconds
memory limit per test 256 megabytes
You are given two positive integer numbers x and y. An array F is called an y-factorization of x iff the following conditions are met:
· There are y elements in F, and all of them are integer numbers;
· .
You have to count the number of pairwise distinct arrays thatare y-factorizations of x. Two arrays A and B are considered different iff there existsat least one index i (1 ≤ i ≤ y) such that Ai ≠ Bi. Since the answer can bevery large, print it modulo 109 + 7.
Input
The first line contains one integer q (1 ≤ q ≤ 105) — the number of testcasesto solve.
Then q lines follow, each containing two integers xi and yi (1 ≤ xi, yi ≤ 106). Each of these linesrepresents a testcase.
Output
Print q integers. i-th integer has to be equal to the number of yi-factorizations of xi modulo 109 + 7.
Example
Input
2
6 3
4 2
Output
36
6
Note
In the second testcase of the example there are six y-factorizations:
· { - 4, - 1};
· { - 2, - 2};
· { - 1, - 4};
· {1, 4};
· {2, 2};
· {4, 1}.
【题意】
给出两个数x、y,问有多少种排列F1,F2,F3……Fn,使得它们的乘积为y,答案模1e9+7。
【思路】
我们首先对x分解质因数,分解成p1c1+ p2c2……的形式。
然后先不考虑符号,把排列中的数Fi都置为1,然后依次处理每个底数,假设它的指数为C,那么这里贡献的次数便是将C个底数分配到y个位置的情况数目。
转化一下,便是放球问题中的球相同,盒子不同,允许空盒的方案数,具体可以看这份博客:传送门
然后每个底数的贡献相乘即可。
最后再考虑符号,我们很容易发现,其实对于y个数的情况,前y-1个数的符号可以任意取定,只要利用最后一个数的符号使得乘积为正即可。
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 2000005;
const ll mod = 1e9+7;
const ll INF = 1e15;
const double eps = 1e-9;
ll fac[maxn];
ll inv[maxn];
ll fast_mod(ll a,ll n,ll Mod)
{
ll ans=1;
a%=Mod;
while(n)
{
if(n&1) ans=(ans*a)%Mod;
a=(a*a)%Mod;
n>>=1;
}
return ans;
}
void init()
{
fac[0]=1;
for(int i=1;i<maxn;i++)
{
fac[i]=(fac[i-1]*i)%mod;
}
inv[maxn-1]=fast_mod(fac[maxn-1],mod-2,mod);
for(int i=maxn-2;i>=0;i--)
{
inv[i]=(inv[i+1]*(i+1))%mod;
}
}
ll C(int n,int m)
{
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
init();
rush()
{
int x,y;
scanf("%d%d",&x,&y);
vector<int>vec;
for(int i=2;i*i<=x;i++) //分解质因数
{
if(x%i==0)
{
int cnt=0;
while(x%i==0)
{
cnt++;
x/=i;
}
vec.push_back(cnt);
}
}
if(x>1) vec.push_back(1);
ll ans=1;
y--;
for(int i=0;i<vec.size();i++)
{
ans*=C(vec[i]+y,y); //模拟放球
ans%=mod;
}
ans=(ans*fast_mod(2,y,mod))%mod; //处理符号
printf("%I64d\n",ans);
}
}