1 月 30 日算法练习-数论

唯一分解定理

唯一分解定理指的是:对于任意一个>1的正整数,都可以以唯一的一种方式分解为若干质因数的乘积。
x = p 1 k 1 ⋅ p 2 k 2 ⋅ … ⋅ p m k m x = p_1^{k_1} \cdot p_2^{k_2} \cdot \ldots \cdot p_m^{k_m} x=p1k1p2k2pmkm
这个式子中的p1,p2是类似2,3,5,7这样的质数。
将单个数字进行质因数方法是,从小到大枚举x的所有可能的质因子,最大枚举到sqrt(x),每遇到一个可以整除的数字i,就不断进行除法直到除尽。最后如果还有x>1,说明还有一个较大的质因子。

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 9;
vector<pair<int, int>> v;

int main() {
   
    int x;
    cin >> x;

    // Enumerate all possible prime factors
    for (int i = 2; i <= x / i; ++i) {
   
        // If it doesn't divide, skip
        if (x % i) continue;

        // If it divides, it must be a prime factor (due to the nature of enumeration from small to large)
        // Count represents the exponent of the current prime factor (i)
        int cnt = 0;

        // Keep dividing until it is no longer divisible
        while (x % i == 0) {
   
            cnt++;
            x /= i;
        }

        v.push_back({
   i, cnt});
    }

    // If x is greater than 1, it means x itself is a prime factor
    if (x > 1) {
   
        v.push_back({
   x, 1});
    }

    // Print the prime factors and their exponents
    for (const auto &i : v) {
   
        cout << i.first << ' ' << i.second << '\n';
    }

    return 0;
}

约数个数定理

通过某个数字的唯一分解: x = p 1 k 1 ⋅ p 2 k 2 ⋅ … ⋅ p m k m x = p_1^{k_1} \cdot p_2^{k_2} \cdot \ldots \cdot p_m^{k_m} x=p1k1p2k2pmkm
我们可以求出x的约数(因数)个数,如果学过线性代数或者有向量相关的知识的话,可以理解为将不同的质因子看作是不同的向量空间或基底,不同质因子之间互不干扰。
也就是说p1的指数的取值是[0,k1]共(k1+1)个,p2,p3…亦然,所以x的约数的个数就是 (k1+1)*(k2+1)*…*(km+1),即: d ( x ) = ∏ i = 1 m ( k i + 1 ) d(x) = \prod_{i=1}^{m}(k_i + 1) d(x)=i=1m(ki+1)

阶乘约数在这里插入图片描述

思路:100!阶乘太大,不能直接求出再求正约数。可以用唯一分解定理和约数个数定理来求约数个数。

#include<iostream>
using namespace std;
const int N = 1e2 + 5;
int a[N];

void f(int x){
   
    
    for(int i=2;i<=x/i;i++){
   
        if(x%i)continue;
        int cnt = 0;
        while(x%i==0){
   
            cnt++;
            x/=i;
        }
        a[i]+=cnt;
    }
    if(x>1)a[x]++;
}

int main(){
   
    for(int i = 1;i<=100;i++)f(i);
    
    long long ans =1;
    
    for(int i=1;i<=100;i++)ans*=(a[i]+1);
    
    cout<<ans<<'\n';
    return 0;
}

在这里插入图片描述

求值

在这里插入图片描述

#include<iostream>
using namespace std;

int check(int x) {
   
    int cnt = 0;
    for(int i=1;i*i<=x;i++){
   
        if(x%i==0){
   
            if(i==x/i)cnt++;
            else cnt+=2;
        }
    }
    return cnt == 100;
}

int main() {
   
    for(int i=1; ;i++){
   
        if(check(i)){
   
            cout<<i<<'\n';
            break;
        }
    }
    return 0;
}

相关推荐

  1. 1 22算法练习

    2024-02-04 03:18:01       54 阅读
  2. 45排序算法总结(1

    2024-02-04 03:18:01       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-04 03:18:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-04 03:18:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-04 03:18:01       82 阅读
  4. Python语言-面向对象

    2024-02-04 03:18:01       91 阅读

热门阅读

  1. 码农也得“开口说话”

    2024-02-04 03:18:01       57 阅读
  2. 建立数据库连接时出错

    2024-02-04 03:18:01       55 阅读
  3. 在 WSL Ubuntu 中安装 SSH 服务器,ssh连接wsl

    2024-02-04 03:18:01       44 阅读
  4. 假期作业2

    2024-02-04 03:18:01       48 阅读
  5. ArrayList的数据结构

    2024-02-04 03:18:01       51 阅读
  6. Mysql-备份与恢复

    2024-02-04 03:18:01       61 阅读
  7. C语言stderr、errno、strerror、perror

    2024-02-04 03:18:01       49 阅读