算法笔记之数论篇《未更完》

1. 试除法判断质数

#include<iostream>
using namespace std;
int n,a;
bool judge(int n) {
    if(n < 2) return false;
    for(int i = 2; i <= n / i; i++) {
        if(n % i == 0) return false; 
    }
    return true;
}
int main() {
    cin>>n;
    while(n--) {
        cin>>a;
        if(judge(a)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}

2. 分解质因数

void divide(int n) {
    for(int i = 2;i <= n / i; i++) {
        if(n % i == 0) {
            int s  = 0;
            while(n % i == 0) {
                 n /= i;
                 s++;
            }
            cout<<i<<" "<<s<<endl;
        }
    }
    if(n > 1) {
        cout<<n<<" "<<1<<endl;
    }
}

3. 筛质数

3.1 朴素做法

// 求出 1 ~ n 中质数的数量,prime 中存的就是 所有的质数
int getPrimeNumber(int n) {
    for(int i = 2; i <= n; i++) {
        if(!st[i]) {
            prime[index++] = i;
        }
        for(int j = i + i; j <= n; j = j + i) {
            st[j] = true;
        } 
    }
    return index;
}

3.2 埃式优化

// 求出 1 ~ n 中质数的数量,prime 中存的就是 所有的质数
int getPrimeNumber(int n) {
    for(int i = 2; i <= n; i++) {
        if(!st[i]) {
            prime[index++] = i;
            for(int j = i + i; j <= n; j = j + i) {
                st[j] = true;
            } 
        }
    }
    return index;
}

4. 试除法求约数

vector<int> getSubmultiple(int n) {
    vector<int> res;
    for(int i = 1; i <= n / i; i++) {
        if(n % i == 0) {
            res.push_back(i);
            if(i != n / i) {
                res.push_back(n / i);
            }
        }
    }
    sort(res.begin(),res.end());
    return res;
}

5. 约数的个数

long long getNum(vector<int> nums) {
    unordered_map<int,int> map;
    for(auto n : nums) {
        for(int i = 2; i <= n / i; i++) {
            if(n % i == 0) {
                while(n % i == 0) {
                    n /= i;
                    s++;
                    map[i] ++;
                }
            }
        }
        if(n > 1) map[n] ++;
    }
    long long res = 1l;
    for(auto x : map) {
        res = res * (x.second + 1) % mod;
    }
    return res;
}

6. 约数之和

long long getSum(vector<int> nums) {
    unordered_map<int,int> map;
    for(auto n : nums) {
        for(int i = 2; i <= n / i; i++) {
            if(n % i == 0) {
                while(n % i == 0) {
                    n /= i;
                    
                    map[i] ++;
                }
            }
        }
        if(n > 1) map[n] ++;
    }
    long long res = 1l;
    for(auto x : map) {
        long long a = x.first, b = x.second;
        long long t = 1;
        while(b --) t = (t * a + 1) % mod; 
        res = res * t % mod;
    }
    return res;
}

7. 最大公约数

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

8. 最小公倍数

long long gcd(int a,int b){
	return  b?gcd(b,a%b):a;
}
// 最小公倍数
long long gcm(int a,int b) {
	return a * b / gcd(a,b);
}

9. 欧拉函数

Acwing

int getPrimeNum(int a) {
    int res  = a;
    // 分解质因数
    for(int i = 2; i <= a / i; i++) {
        if(a % i == 0) {
            res = res / i * (i - 1);
            while(a % i == 0) {
                a = a / i;
            }
        }
    }
    if(a > 1) {
        res = res / a * (a - 1);
    }
    return res;
}

10. 快速幂

#include<iostream>
using namespace std;
int main() {
    int n;
    cin>>n;
    while(n--) {
        int a,b,p;
        cin>>a>>b>>p;
        int res = 1 % p;
        while(b) {
            if(b & 1) res = res * 1LL * a % p;
            a = a * 1LL * a % p;
            b>>=1;
        }
        cout<<res<<endl;
    }
    return 0;
}

11. 求组合数

void init() {
    for(int i = 0; i < N; i++) {
        for(int j = 0; j <= i; j++) {
            if(!j) {
                c[i][j] = 1;
            }else {
                c[i][j] = (c[i-1][j] + c[i-1][j-1])%mod;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佩奇inging

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值