Primes and Multiplication

Primes and Multiplication

Let’s introduce some definitions that will be needed later.

Let prime(x) be the set of prime divisors of xx. For example, prime(140) ={2,5,7}, prime(169) ={13}.

Let g(x,p) be the maximum possible integer p ^k where k is an integer such that x is divisible by p ^k. For example:

  • g(45,3) =9 (45 is divisible by 3 ^2=9 but not divisible by 3 ^3=27),
  • g(63,7) =7 (63 is divisible by 7 ^1=7 but not divisible by 7 ^2=49).

Let f(x,y) be the product of g(y,p) for all p in prime(x) . For example:

  • f(30,70) =g(70,2)g(70,3)g(70,5) =2 ^1⋅3 ^0⋅5 ^1=10,
  • f(525,63) =g(63,3)g(63,5)g(63,7) =3 ^2⋅5 ^0⋅7 ^1=63.

You have integers x and n. Calculate f(x,1)f(x,2) ⋅…⋅ f(x,n) mod(10^9+7).

Input
The only line contains integers x and n (2≤x≤10^ 9,1≤n≤10^18) — the numbers used in formula.

Output
Print the answer.

Examples
input
10 2
output
2

input
20190929 1605
output
363165664

input
947 987654321987654321
output
593574252

Note
In the first example, f(10,1) = g(1,2)g(1,5) =1, f(10,2) = g(2,2)g(2,5) =2.

In the second example, actual value of formula is approximately 1.597⋅10^171. Make sure you print the answer modulo (109+7).

In the third example, be careful about overflow issue.

思路
首先分析一波感觉不会很难,告诉我们prime(x)就是求x的质因数,一个循环可以出来,然后g(a,b)就是说a能够整除b的最大次方的数字,然后f(a,b)就是求g(b,d),d为a的质因数,我们要求的是f(x,1)到f(x,n)的乘积。
然后我们可以看到对于每一个a的质因数d,对于1-b的数字而言:
f(b,a)=a,f(b,2a)=a,f(b,3a)=a…f(b,a*a)=a ^2,f(b,(a+1)*a)=a ^2…
(就是只有a的倍数才能得到f函数的值)
那么对于每一个质因数,我们可以先求出一共有多少个a相乘,然后快速幂即可求出结果

代码如下:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int mx=1e5+10;
const int mod=1e9+7;

vector<ll>s;
ll x,n,m,ans;

ll qpow(ll a,ll b){  //快速幂取模
	ll tmp=1;
	while(b){
		if(b&1)
		tmp=tmp*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return tmp;
}

int main(){
	ans=1ll;
	scanf("%lld%lld",&x,&n);
	m=x;
	for(ll i=2;i*i<=m;i++){
		if(m%i==0){
		s.push_back(i); //先将质因子存起来
		while(m%i==0)
		  m/=i;
		}
	}
	if(m>1) s.push_back(m);
	for(ll i=0;i<s.size();i++){
		m=n;
		ll now=0;
		while(m>=s[i]){
		now+=m/s[i];//这一步对我而言最妙,这个地方处理难死我了
		m/=s[i];
		}
		ans=ans*qpow(s[i],now)%mod;
	}
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值