codeforces 893E Counting Arrays (组合数学)

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
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 将 一个数分为 y份 它们的乘为 x 问几种情况

分析:将 x分解质因数 然后进行隔板法取。因为有负的情况,最后乘上 2^(y-1)就可以了~

AC代码:
//C n+m-1 m;
//2^(y-1); 

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
using namespace std;
vector<int>v[1000500];
const int mod=1000000007;
int cur[1000500];
long long inv[2000050];
long long fc[2000050];
long long vv[1000500];
long long f(long long a,long long b);
void init()
{
	memset(cur,0,sizeof(cur));
	fc[0]=1LL;
	for(int i=1;i<2000000;i++)
	fc[i]=fc[i-1]*i%mod;
	for(int i=0;i<2000000;i++)
	inv[i]=f(fc[i],mod-2);
	for(int i=1;i<=1000000;i++)
	vv[i]=i;
	cur[1]=1;
	for(int i=2;i<=1000000;i++)
	{
		if(!cur[i])
		{
			v[i].push_back(1);
			for(int j=i+i;j<=1000000;j+=i)
			{
				cur[j]=1;
				int q=0;
				while(vv[j]%i==0)
				{
					q++;
					vv[j]/=i;
				}
				v[j].push_back(q);
			}
		}
	}
}
long long f(long long a,long long b)
{
	long long c=1;
	while(b)
	{
		if(b&1)
		{
			c*=a;
			c%=mod;
		}
		a*=a;
		a%=mod;
		b>>=1;
	}
	return c;
}
int main()
{
	
	init();
	int T;
	scanf("%d",&T);
	while(T--)
	{
		long long x,y;
		scanf("%lld%lld",&x,&y);
		long long ans=1;
		for(int i=0;i<v[x].size();i++)
		{
			int q=v[x][i];
			ans=ans*fc[q+y-1]%mod*inv[q]%mod*inv[y-1]%mod;
		}
		//printf("!! %lld\n",ans);
		//printf("~~ %lld\n",f(2,y-1));
		ans*=f(2,y-1);
		ans%=mod;
		printf("%lld\n",ans);
	}
} 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值