OVSolitario-io

导航

数论

整除性:

b除以非零数a,商为整数,余数为0,记为a|b
发现,当a整除b时,都存在与之对应的b/a整除b,所以只枚举根号b即可

且乘法效率更优,但可能存在i*i溢出问题
额外判断当k != n/k时,全部加入到答案中去

求因数:对于是否<=想36即可,36=6*6所以包含等于

证明:
image

点击查看代码
for(int i = 1; i * i <= n; ++ i) {
    if(n % i == 0) {
        q[k ++] = i;
        if(n / i != i) q[k ++] = n / i;
    }
}

判断质数:

点击查看代码
for(int i = 2; i * i <= n; ++ i) {
    if(n % i == 0) return 0;
}

质数筛:

当i为质数时,i的all倍数一定为合数
所以采用建表方式将2~n,顺序将i的倍数删去,余下即为all合数,后查表即可

点击查看代码
a[0] = a[1] = 1;
for(int i = 2; i * i <= n; ++ i) {
    if(!a[i]) {//我是素数,我的倍数一定为合数
        for(int j = i * 2; j <= n; j += i) {//删去all倍数
            a[j] = 1;
        }
    }
}   
for(int i = 2; i <= n; ++ i) {//建表
    if(!a[i]) b[++ k] = i;
}

while(q -- ) {//O(1)查询
    cin >> x;
    cout << b[x] << endl;
}

对于分解质因数:

当范围在11e9时,组数小但范围大,采用正常方法
而对于n
1e6时,采用建质数表方式(判掉合数),灵活的采用算法解题

GCD&LCM:

辗转相除法: O(log)

GCD:gcd(x, y) = gcd(y, x mod y), x > y且x mod y != 0

利用除数和余数反复做除法,余数为0取当前数为Gcd

点击查看代码
int Gcd(int x, int y) {
    if(y == 0) return x;
    return Gcd(y, x % y); 
}

其中,#include 头文件中,包含STL:__gcd(x, y)

__gcd(x, y);

且STL中x,y大小顺序任意

LCM:lcm(a, b) = a * b / gcd(a, b)

点击查看代码
long long Lcm = (long long)a * b / Gcd(a, b);

其中a * b可能为极大值,因此需要类型转换为long long

算数基本定理:

分解质因数:

点击查看代码
int main() {
    cin >> n;
    tmp = n;
    for(int i = 2; i * i <= n; ++ i) {
        while(tmp % i == 0) {
            cout << i << ' ';
            tmp /= i;   
        }
        if(tmp == 1) break;
    }
    if(tmp != 1) cout << tmp << endl;

posted on 2025-05-18 10:43  TBeauty  阅读(259)  评论(0)    收藏  举报