求合数的所有素因子

求合数的所有素因子

唯一分解定理

对正整数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的分解

应用

截屏2020-07-22 下午4.35.10

简单分析过后得到: $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;
}

posted @ 2020-07-22 16:42  popozyl  阅读(410)  评论(0编辑  收藏  举报