acwing 质数 约数 欧拉函数

本文介绍了使用C++实现的几种数学算法,包括质数判定、分解质因数、试除法求约数乘积的约数个数、最大公约数计算以及欧拉函数的求解,展示了基础数学在编程中的应用。
摘要由CSDN通过智能技术生成

质数

试除法定质数

bool is_prime(int num)
{
    if(num < 2)
        return false;
    for(int i = 2; i <= num / i; ++i)
        if(num % i == 0)
            return false;
    return true;
}

分解质因数

	// 一个数最小的因数就是质因数
    int n, num;
    cin >> n;
    for(int j = 0; j < n; ++j)
    {
        cin >> num;
        for(int i = 2; i <= num / i; ++i)
        {
            if(num % i == 0)
            {
                int cnt = 0;
                while(num % i == 0)
                {
                    num /= i;
                    cnt++;
                }
                cout << i << " " << cnt << endl;
            }
        }
        if(num  > 1)
            cout << num << " " << 1 << endl;
        cout << endl;
    }

筛质数

void get_prime()
{
    for(int i = 2; i <= n; ++i)
    {
        if(visited[i] == false)
            primes[idx++] = i;  // 埃式筛法
        for(int j = i + i; j <= n; j += i)
            visited[j] = true;
    }
}

约数

试除法求约数


int main()
{
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        cin >> num;
        vector<int> ret;            // 包含1和num本身
        for(int j = 1; j <= num / j; ++j)
        {
            if(num % j == 0)
            {
                ret.push_back(j);   // 这里可同时获得两个约数
                if(j != num / j)
                    ret.push_back(num / j);
            }
        }
        sort(ret.begin(), ret.end());
        for(auto a : ret)
            cout << a << " ";
        cout << endl;
    }
    return 0;
}

乘积的约数个数

const int mod = 1e9 + 7;
int main()
{
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        cin >> num;
        for(int j = 2; j <= num / j; ++j)
        {               // 试除法求质因数及其指数
            while(num % j == 0)
            {
                num /= j;
                all[j]++;
            }
        }
        if(num != 1)    // num本身是一个大的质因数
            all[num]++;
    }
    long long ret = 1;
    for(auto &a : all)  // 乘积总约数个数:质因数指数+1的乘积
        ret = ret * (a.second + 1) % mod;
    cout << ret;
    return 0;
}

最大公约数

int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}

欧拉函数

在这里插入图片描述


int main()
{
    int n;
    cin >> n;
    while(n--)
    {
        int num;
        cin >> num;
        int ret = num;
        for(int i = 2; i <= num / i; ++i)
        {
            if(num % i == 0)
            {               // 注意运算顺序
                ret = ret / i * (i - 1) ;
                while(num % i == 0)
                    num /= i;
            }
        }
        if(num > 1)
            ret = ret / num * (num - 1) ;
        cout << ret << endl;
    }
    return 0;
}

筛法求欧拉函数和

void get_phi(int n)
{
    phi[1] = 1;
    for(int i = 2; i <= n; ++i)
    {
        if(visited[i] == false)
        {
            primes[idx++] = i;              // 获取质数
            phi[i] = i - 1;                 // 质数的欧拉函数
        }
        
        for(int j = 0; primes[j] <= n / i; ++j)
        {
            visited[primes[j] * i] = true;  // 标记非质数
            if(i % primes[j] == 0)
            {                               // p[j]为i的质因数
                phi[primes[j] * i] = phi[i] * primes[j];
                break;
            }
            else                            // p[j]不为i的质因数,要另乘一个p[j]质因数项
                phi[primes[j] * i] = phi[i] * primes[j] / primes[j] * (primes[j] - 1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值