C.Anadi and Domino
题意
给定
,求
定义1: 对于
,定义
是
可以整除
的最大次幂,那么
例如
,
可以整除
,但是
就不可以整除
,所以
定义2:
思路
现将
用试除法分解质因子,然后根据一个推论:
[1,n] 中因子中含有 i 的数字个数是
在kuangbin的练习中(J)也用过这个推论。
找出所有的然后每次累乘 qpow(p[i],n / p[i]),在乘的过程中取余即可。(qpow是快速幂)
下面以 来举例:
先打出所有的
,分解
是
先将
中因子有
的数字 中的
先提出来乘,
一共
个数 ,就乘上
,
这样上图就变成这样
灰色代表我们已经乘过了
之后将
(整除),得到
,再找
中 因子有
的数字,是
一共
个数,乘上
。
这一步相当于把第二张图中,第
项和第
项的
也给乘掉。
这样所有的
就都乘完了
之后的质因子就都是这样乘,这种方法有点埃式筛法的意思。
#include<bits/stdc++.h>
#define ll __int64
using namespace std;
const int N = 1e5 + 7;
const int mod = 1e9 + 7;
int c[N],p[N],tot = 0;
int prime[N],prime_tot = 0;
bool prime_tag[N];
ll x,n;
void get_prime(){
for(ll i = 2; i < N; i++) prime_tag[i] = true;
for(ll i = 2; i < N; i++){
for(ll j = i * i ; j < N; j += i)
prime_tag[j] = false;
}
for(int i = 2; i < N; i++)
if(prime_tag[i]) prime[prime_tot++] = i;
}
ll qpow(ll a,ll b){
ll res = 1;
while(b){
if(b & 1){
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}
void divide(ll n) {
for(int i = 0 ; i < prime_tot && prime[i]*prime[i] <= n; i++) {
if(n % prime[i] == 0) {
p[++tot] = prime[i];
while(n % prime[i] == 0 && n > 1) {
c[tot]++;
n /= prime[i];
}
if(n == 1) break;
}
}
if(n > 1) {
p[++tot] = n;
c[tot] = 1;
}
}
ll solve(ll m){
ll res = 1,t;
divide(x);
for(int i = 1 ; i <= tot; i++){
t = m;
while(t){
res = res % mod * qpow(p[i],t / p[i]) % mod;
t /= p[i];
//printf("res = %I64d \n",res);
}
}
return res;
}
int main(){
ll ans;
get_prime();
scanf("%I64d%I64d",&x,&n);
ans = solve(n);
printf("%I64d",ans);
return 0;
}