zoukankan      html  css  js  c++  java
  • Luogu 3911 最小公倍数之和

    感觉自己被早上的名校协作体和下午的数学题虐哭了,每天为自己的菜发愁……

    发现$a_{i}$很小,开一个桶记一下每个数 出现的个数,设$c_{i} = sum_{j = 1}^{n}(a_{j} == i)$。

    我们知道$lcm(i, j) == frac{ij}{gcd(i, j)}$。

    记$m = max(a_{i})$。

    那么  $sum_{i = 1}^{n}sum_{j = 1}^{n}lcm(a_{i}, a_{j})   = sum_{i = 1}^{m}sum_{j = 1}^{m}frac{ij}{gcd(i, j)} * c_{i} * c_{j}$。

    反演一下,得到  $sum_{d = 1}^{m}dsum_{t = 1}^{left lfloor frac{m}{d} ight floor}t^{2} * mu (t)sum_{u = 1}^{left lfloor frac{m}{dt} ight floor}sum_{v = 1}^{left lfloor frac{m}{dt} ight floor}u * v * c_{dtu} * c_{dtv}$。

    枚举$T = dt$,得到   $sum_{T = 1}^{m}(T (sum_{d | T}d * mu (d)))(sum_{u = 1}^{left lfloor frac{m}{T} ight floor}u * c_{Tu})(sum_{v = 1}^{left lfloor frac{m}{T} ight floor}v * c_{Tv})$。

    设$h(T) = sum_{d | T}d * mu (d)$,$g(T) = sum_{d = 1}^{left lfloor frac{m}{T} ight floor}d * c_{Td}$,那么最后的答案就变成了$sum_{T = 1}^{m}T * h(i) * g^{2}(i)$。

    发现$h(i)$是一个积性函数,有$h(1) = 1, h(p) = 1 - p, h(p^{k}) = h(p)$,可以线性筛。

    而$g(i)$只要暴力算就可以了。

    时间复杂度$O(nlogn)$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 5e4 + 5;
    
    int n, m = 0, pCnt = 0, pri[N], low[N];
    ll h[N], g[N], c[N];
    bool np[N];
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9'|| ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMax(int &x, int y) {
        if(y > x) x = y;
    }
    
    inline void sieve() {
        h[1] = 1;
        for(int i = 2; i <= m; i++) {
            if(!np[i]) {
                pri[++pCnt] = i;
                low[i] = i;
                h[i] = (ll)1 - i;
            }
            for(int j = 1; j <= pCnt && i * pri[j] <= m; j++) {
                np[i * pri[j]] = 1;
                if(i % pri[j] == 0) {
                    low[i * pri[j]] = low[i] * pri[j];
                    if(low[i] == i) h[i * pri[j]] = h[i];
                    else h[i * pri[j]] = h[i / low[i]] * h[pri[j] * low[i]];
                    break;
                }
                low[i * pri[j]] = pri[j];
                h[i * pri[j]] = h[i] * h[pri[j]];
            }
        }
        
    /*    for(int i = 1; i <= m; i++)
            printf("%lld ", h[i]);
        printf("
    ");   */
    }
    
    int main() {
        read(n);
        for(int i = 1; i <= n; i++) {
            ll x; read(x);
            c[x]++;
            chkMax(m, x);
        }    
        
    /*    for(int i = 1; i <= m; i++)
            printf("%lld ", c[i]);
        printf("
    ");   */
        
        sieve();
        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= m / i; j++)
                g[i] += c[i * j] * j;
        
    /*    for(int i = 1; i <= m; i++)
            printf("%lld ", g[i]);
        printf("
    ");   */
        
        ll ans = 0LL;
        for(int i = 1; i <= m; i++)
            ans += i * h[i] * g[i] * g[i];
        
        printf("%lld
    ", ans);
        return 0;
    }
    View Code

       

  • 相关阅读:
    java fastJson
    动态 商品属性
    添加营业时间
    ivew 表格中的input数据改变就会失去焦点
    小程序-setData
    小程序 css3走马灯效果
    iview 表单验证
    vue iview tree checked改变 不渲染的问题
    pl/sql中文乱码
    sql-plus无法连接解决
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9579211.html
Copyright © 2011-2022 走看看