原题链接
Let’s introduce some definitions that will be needed later.
Let prime(x) be the set of prime divisors of x. For example, prime(140)={2,5,7}, prime(169)={13}.
Let g(x,p) be the maximum possible integer pk where k is an integer such that x is divisible by pk. For example:
g(45,3)=9 (45 is divisible by 32=9 but not divisible by 33=27),
g(63,7)=7 (63 is divisible by 71=7 but not divisible by 72=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)=21⋅30⋅51=10,
f(525,63)=g(63,3)⋅g(63,5)⋅g(63,7)=32⋅50⋅71=63.
You have integers x and n. Calculate f(x,1)⋅f(x,2)⋅…⋅f(x,n)mod(109+7).
Input
The only line contains integers x and n (2≤x≤109, 1≤n≤1018) — the numbers used in formula.
Output
Print the answer.
inputCopy
10 2
outputCopy
2
inputCopy
20190929 1605
outputCopy
363165664
inputCopy
947 987654321987654321
outputCopy
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⋅10171. Make sure you print the answer modulo (109+7).
In the third example, be careful about overflow issue.
题意
prime(x):x的所有素因子
g(x,p):使p^k尽可能的大,同时满足x%p ^ k=0,最大的p ^ k就是g(x,p)的值
f(x,y):g(y,x1) * g(y,x2) * …*g(y,xn).(x1…xn为x的素因子)
给定x和n,求f(x,1) * f(x,2) * …f(x,n)的值
思路
对于数论这种题,我一般都是先推公式,然后再想用到哪些方法
1.我们举个例子,设x=6,n=6; prime(x)=2,3
2.然后模拟式子,f(x,1) * f(x,2) * f(x,3) * f(x,4) * f(x,5) * f(x,6)
3.继续推:g(1,2)*g(1,3) * g(2,2)*g(2,3) * g(3,2)*g(3,3) * g(4,2)*g(4,3) * g(5,2)*g(5,3) * g(6,2)*g(3,3)
4.继续化简:(第一部分) g(1,2)*g(2,2)*g(3,2)*g(4,2)*g(5,2)*g(6,2)
5.继续化简:(第二部分) g(1,3)*g(2,3)*g(3,3)*g(4,3) * g(5,3)*g(6,3)
6.到现在就全部化简完成了,那么我们看g(x,y)函数,就是表示y^k 最大且 x%y ^ k==0 进而我们可以知道,其实就是g(x,p)可以转化为p ^ k,而k可以看成p作为质因子在x中出现的次数。
7.现在问题基本解决,基本算法:快速幂,试除法分解因数
代码中有一块地方不好理解,额外解释一下
4.5两步如何求解普通求解:直接暴力1-n,求出每个的幂,然后相加,但是会超时
转化思维:g(x,p) p是x的质因子,只有x是p的倍数才能取余等于0具体模拟:g(1,2)*g(2,2)*g(3,2)*g(4,2)*g(5,2)*g(6,2)这个式子中,g(2,2) 贡献1次幂, g(4,2)贡献2次幂,g(6,2)贡献1次幂 ,所以sum=1+2+1=4;然后用快速幂求的24=16
代码实现:因为只有是倍数才会出现,所以6/2=3; 2的1倍,2的2倍,2的3倍,之后剩余3 ,3/2=1 ,这2的1倍 贡献为4
//遍历每一个质因子
for(int i=0;i<cnt;i++){
ll s=n;
ll sum=0;
//求质因子的幂
while (s){
s/=primes[i];
sum+=s;
}
res=(res*qmi(primes[i],sum))%mod;
}
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
ll x, n;
ll primes[100001];
ll cnt;
//试除法求除x的所有质因子
void divide(int x){
for(int i=2;i<=x/i;i++){
if(x%i==0){
primes[cnt++]=i;
while(x%i==0){
x/=i;
}
}
}
if(x>1) primes[cnt++]=x;
}
//快速幂模板
ll qmi(ll m,ll k){
ll res=1l;
while (k){
if(k&1) res=res*m%mod;
m=m*m%mod;
k>>=1;
}
return res;
}
int main() {
cin >> x >> n;
divide(x);
ll res=1;
for(int i=0;i<cnt;i++){
ll s=n;
ll sum=0;
while (s){
s/=primes[i];
sum+=s;
}
res=(res*qmi(primes[i],sum))%mod;
}
cout<<res<<endl;
return 0;
}