http://codeforces.com/contest/893/problem/E
题意:一个数组中有y个数字,数字的乘积为x 问能够构造多少这样的数组
思路:首先将x质因子分解,那么相当于把每个质因子安排在y个位置上,有些位置可以为空,问有多少种放置方法。这就相当于把n个球,放在m个盒子里,允许为空一样。采用隔板法,结果为C(m+n-1,m-1) 相当于需要m-1个隔板将其分成m组,由于可以为空,先在每个盒子中放一个球即可
还有正负号的问题 每次选择偶数个变为负号 总共就有
C(n,0)+c(n,2)… 即2n-1 和之前算出的组数相乘即可
阶层和质因子预处理下,不然会超时
#include<bits/stdc++.h>
#define fi first
#define se second
#define log2(a) log(n)/log(2)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define tim printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
using namespace std;
typedef long long ll;
typedef long long LL;
typedef pair<int, int> P;
typedef pair<P, ll> LP;
const ll inf = 1e9+100;
const int N = 2e6 + 10;
const ll mod = 1e9+7;
const int base = 131;
const double pi = acos ( -1 );
const double eps = 1e-8;
inline ll ksm(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
#define a(i,j) a[(i-1)*m+(j)]
#define b(i,j) b[(i-1)*m+(j)]
unordered_map<ll, ll> mp;
//ll vis[N],num[N], a[N], b[N],in[N];
ll n, m, k, x, y, z,q;
ll cx, cy, cz,cnt, ans, sum, flag, t, ff,w;
//vector<int> v[N],res;
//string s;
//P p[N];
ll fac[N],did[N];
ll phi[N],prime[N],inv[N];
void init()
{
fac[0]=1;
inv[0]=1;
for(int i=1;i<=2e6;i++)
{
fac[i]=(fac[i-1]*i)%mod;
inv[i]=ksm(fac[i],mod-2);
}
int tot=0;
phi[1]=1;
for(int i=2;i<=2e6;i++)
{
if(!did[i])
{
prime[++tot]=i;
}
for(int j=1;j<=tot&&i*prime[j]<=2e6;j++)
{
did[i*prime[j]]=1;
if(i%prime[j]==0)
{
break;
}
}
}
}
ll c(ll i,ll j)
{
return ((fac[j]*inv[i])%mod*inv[j-i])%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>q;
init();
while(q--)
{
cin>>n>>m;
ans=1;
for(int i=1;prime[i]*prime[i]<=n;i++)
{
x=0;
if(n%prime[i]==0)
{
while(n%prime[i]==0)
x++,n/=prime[i];
ans=(ans*c(m-1,x+m-1))%mod;
}
}
if(n>1) ans=(ans*c(m-1,m))%mod;
cout<<(ans*ksm(2,m-1))%mod<<endl;
}
}