洛谷 P1403 [AHOI2005]约数研究

本文转载自: https://www.cnblogs.com/ldysy2012/p/10390857.html

前导知识链接

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

/**
 * 功能:线性筛出约数个数与约数和
 * Tag:模板,约数个数,约数和
 */
const int N = 1e6 + 10;
int n;
int primes[N];      //质数数组
int idx;            //质数数组下标游标
bool st[N];         //是否已被筛出
int d[N];           //约数个数数组
int sigma[N];       //约数和数组

void get_divisor(int n) {
    //积性函数的出发值
    d[1] = sigma[1] = 1;

    for (int i = 2; i <= n; i++) {  //倍数
        if (!st[i])primes[++idx] = i, d[i] = 2, sigma[i] = i + 1;
        for (int j = 1; i * primes[j] <= n & j <= idx; j++) {
            st[i * primes[j]] = true;
            d[i * primes[j]] = d[i] << 1;
            sigma[i * primes[j]] = sigma[i] * (primes[j] + 1);
            if (i % primes[j] == 0) {
                d[i * primes[j]] -= d[i / primes[j]];
                sigma[i * primes[j]] -= primes[j] * sigma[i / primes[j]];
                break;
            }
        }
    }
}

LL res;

int main() {
    cin >> n;
    //开始筛约数个数,约数和
    get_divisor(n);
    //输出约数个数和
    for (int i = 1; i <= n; i++) res += d[i];
    cout << res << endl;
    return 0;
}
posted @ 2021-06-28 15:13  糖豆爸爸  阅读(58)  评论(0编辑  收藏  举报
Live2D