zoukankan      html  css  js  c++  java
  • Solution -「数论」「HDU」Professor Ben

    Description

    (Q) 个询问。每次给定一个正整数 (n),求它的所有因数的质因数个数的和。


    Solution

    就讲中间的一个 Trick。

    我们定义正整数 (x)(f(x)) 个因数,且存在一函数 (g(x) = sum_{i | x} f^3(i)),显然 (g(x))(x) 对应的答案。

    那么,若 (x = p^a),则由因数个数定理可得: (f(x) = a + 1)

    且其因数集合可表示为:({p^0, p^1, ... , p^a})。故有 (g(x) = sum_{i = 0}^{a} f^3(p^i) = sum_{i = 0}^{a} (i + 1)^3)

    (x) 的范围加以推广。

    (x = p^a q^b),则 (f(x) = (a + 1) imes (b + 1))

    且其因数集合可表示为:({{p^0 q^0, p^0 q^1, ..., p^0 q^b}, {p^1 q^0, p^1 q^1, ..., p^1 q^b}, ... , {p^a q^0, p^a q^1, ..., p^a q^b}})。故有 (g(x) = sum_{i = 0}^{a}sum_{j = 0}^{b} f^3(p^i q^j) = sum_{i = 0}^{a}sum_{j = 0}^{b} (i + 1)^3 (j + 1)^3)

    注意到 (g(p^a) = sum_{i = 0}^{a} (i + 1)^3, g(q^b) = sum_{j = 0}^{b} (j + 1)^3)

    所以有 (g(x) = g(p^a q^b) = g(p^a) imes g(q^b))。显然可推广至结论:

    [g(x) = g(p_1^{a_1} p_2^{a_2} ... p_k^{a_k}) = prod_{i = 1}^{k} g(p_i^{a_i}) ]

    然后就可以当结论题切掉它。


    Code

    #include <cstdio>
    
    typedef long long LL;
    int Max(int x, int y) { return x > y ? x : y; }
    int Min(int x, int y) { return x < y ? x : y; }
    int Abs(int x) { return x < 0 ? -x : x; }
    
    int read() {
        int k = 1, x = 0;
        char s = getchar();
        while (s < '0' || s > '9') {
            if (s == '-')
                k = -1;
            s = getchar();
        }
        while (s >= '0' && s <= '9') {
            x = (x << 3) + (x << 1) + s - '0';
            s = getchar();
        }
        return x * k;
    }
    
    void write(LL x) {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x > 9)
            write(x / 10);
        putchar(x % 10 + '0');
    }
    
    void print(LL x, char s) {
        write(x);
        putchar(s);
    }
    
    const int MAXN = 5e6 + 5;
    
    bool flag[MAXN];
    int num[MAXN], len = 0;
    LL w[MAXN];
    
    void Euler(int n) {
        flag[1] = true;
        for (int i = 2; i <= n; i++) {
            if (!flag[i])
                num[++len] = i;
            for (int j = 1; j <= len; j++) {
                if (i * num[j] > n)
                    break;
                flag[i * num[j]] = true;
                if (i % num[j] == 0)
                    break;
            }
        }
    }
    
    int main() {
        Euler(MAXN - 5);
        for (int i = 1; i < 23; i++)
            for (int j = 0; j <= i; j++) w[i] += (1 + j) * (1 + j) * (1 + j);
        int n = read();
        for (int i = 1, x; i <= n; i++) {
            x = read();
            LL res = 1;
            for (int j = 1; num[j] * num[j] <= x; j++) {
                int cnt = 0;
                while (x % num[j] == 0) {
                    x /= num[j];
                    cnt++;
                }
                res *= w[cnt];
            }
            if (x > 1)
                res *= w[1];
            print(res, '
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    在esx上 docker的网络桥接
    docker 配置桥接网络
    docker 配置桥接网络
    perl 创建包
    perl 创建包
    perl 一个简单的面向对象的例子
    perl 一个简单的面向对象的例子
    perl 对象 bless 引用
    【技术角度看问题之一】ARM到底是个啥?
    【nodejs原理&源码赏析(3)】欣赏手术级的原型链加工艺术
  • 原文地址:https://www.cnblogs.com/Chain-Forward-Star/p/15138437.html
Copyright © 2011-2022 走看看