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;
}