codeforces 893e Counting Arrays

17 篇文章 0 订阅
E. Counting Arrays
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 that are y-factorizations of x. Two arrays A and B are considered different iff there exists at least one index i (1 ≤ i ≤ y) such that Ai ≠ Bi. Since the answer can be very large, print it modulo 109 + 7.

Input

The first line contains one integer q (1 ≤ q ≤ 105) — the number of testcases to solve.

Then q lines follow, each containing two integers xi and yi (1 ≤ xi, yi ≤ 106). Each of these lines represents 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
Copy
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}.

题意:求长度为y的整数数组,它的所有数的乘积为x的数组的个数。

题解:

首先我们对x进行质因数分解,这样就转化成了若干个独立的小问题。

之后我们发现其实就是把x的质因子分配到y数组的数字上的方案数相乘,放球问题,C(y-1+k,y-1)。

因为可以为负数,所以最后答案乘上C(y,0)*C(y,2)*C(y,4)*......

这个数字是2^(y-1)

代码:

#include <bits/stdc++.h>  
using namespace std;  
typedef long long ll;  
ll q,a[30],x,y,fac[2000005],two[2000005];  
ll qmod(ll n,ll k)  
{  
    ll ans=1;  
    while(k) 
    {  
        if(k&1) ans=ans*n%1000000007;  
        k>>=1;  
        n=n*n%1000000007;  
    }  
    return ans%1000000007;  
}  
ll inv(ll n){return qmod(n,1000000005);}  
ll C(ll m,ll n)  
{  
    ll M=fac[m];  
    ll NM=fac[n]*fac[m-n]%1000000007;  
    NM=M*inv(NM)%1000000007;  
    return NM;  
}
int main()  
{  
    fac[0]=two[0]=1;  
    for(int i=1;i<2000005;i++) 
    {  
        two[i]=two[i-1]*2LL%1000000007;  
        fac[i]=fac[i-1]*i%1000000007;  
    }  
    cin>>q;
    while(q--) 
    {  
        memset(a,0,sizeof(a));  
        int tot=0;  
        ll ans=1;  
        scanf("%I64d%I64d",&x,&y);  
        for(int i=2;i*i<=x;i++) 
            if(x%i==0) 
                for(tot++;x%i==0;x/=i) 
                    a[tot]++;
        if(x!=1) a[++tot]=1;  
        for(int i=1;i<=tot;i++) ans=ans*C(y+a[i]-1,a[i])%1000000007;  
        ans=ans*two[y-1]%1000000007;  
        printf("%I64d\n",ans);  
    }  
}  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值