求合数的所有素因子
求合数的所有素因子
唯一分解定理
对正整数N,存在唯一的排列\(\{p_1,p_2,....\}\)使得\(N = \{p_1^{e_1}*p_2^{e_2}*...*p_k^{e_k}\}\)
其中{p_1 < p_2 < p_3 < ... < p_n} ,{p_i}是素数
求合数N的分解:
- 先筛法求素数
- 再循环求N的分解
应用
简单分析过后得到: $f_c(x) = c ^ {num(x)} $
其中\(num(x)\) 为将x唯一分解后的所有素数的指数之和(即\(e_1+e_2+...+e_n\))
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
vector<int> vec;
void get_prime(vector<int> & prime,int upper_bound){ // 传引用
if(upper_bound < 2)return;
vector<bool> Is_prime(upper_bound+1,true);
for(int i = 2; i <= upper_bound; i++){
if(Is_prime[i])
prime.push_back(i);
for(int j = 0; j < prime.size() and i * prime[j] <= upper_bound; j++){
Is_prime[ i*prime[j] ] = false;
if(i % prime[j] == 0)break;// 保证了一个数只被筛一次。
}
}
}
ll quick_pow(ll base,ll idx){
ll ans = 1;
while (idx) {
if(idx&1){
ans *= base;
ans %= mod;
}
idx >>= 1;
base *= base;
base %= mod;
}
return ans;
}
int num(int n){
int ans = 0;
int m = (int)sqrt(n+0.5);
for(int i=0;vec[i]<=m;i++){
while(n%vec[i]==0){
n/=vec[i];
ans++;
}
}
if(n != 1)
ans++;
return ans;
}
int main(){
ll n;
scanf("%lld",&n);
get_prime(vec,1000000); // 欧拉筛
while (n--) {
ll c,x;
scanf("%lld %lld",&x,&c);
ll p = num(x);
printf("%lld\n",quick_pow(c,p));
}
return 0;
}
---- suffer now and live the rest of your life as a champion ----