zoukankan      html  css  js  c++  java
  • SPOJ LCMSUM

    题意是求:

        $sum_{i = 1}^{n}lcm(i, n)$

        $= sum_{i = 1}^{n}frac{ni}{gcd(i, n)}$

        $= nsum_{i = 1}^{n}frac{i}{gcd(i, n)}$

        $= nsum_{d|n}sum_{i = 1}^{n}d*[gcd(i, n)==d]$

        $= nsum_{d|n}sum_{i = 1}^{frac{n}{d}}i*[gcd(i, frac{n}{d})==1]$

        $= nsum_{d|n}sum_{i = 1}^{d}i*[gcd(i, d)==1]$

    设$h(d) = sum_{i = 1}^{d}i*[gcd(i, d)==1]$,其实是求在$1,2,3...d$的范围内与$d$互质的数的总和,当$d>1$时,它就等于$frac{phi (d) * d}{2}$

    证明:

        因为$gcd(i, d) == 1$,那么也有$gcd(d - i, d) == 1$,所以假如$i$与$d$互质,那么$d - i$也与$d$互质,它们的和是$d$,也就是说在$1, 2, 3, ..., d$中,这样的数对一共有$frac{phi (d)}{2}$个,每一对的和是$d$,所以$h(d) = frac{phi (d) * d}{2}$

    $h(1)$当然是等于$1$的。

    这样我们线性筛出欧拉函数$phi (i)$,然后再暴力算$h(i)$,最后询问的时候输出$h(n) * n$.

    时间复杂度是$O(MaxNlogMaxN + T)$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e6 + 5;
    const int Maxn = 1e6;
    
    int testCase, pCnt = 0, pri[N];
    ll h[N], phi[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;
    }
    
    void sieve() {
        phi[1] = 1LL;
        for(int i = 2; i <= Maxn; i++) {
            if(!np[i]) pri[++pCnt] = i, phi[i] = i - 1;
            for(int j = 1; j <= pCnt && pri[j] * i <= Maxn; j++) {
                np[i * pri[j]] = 1;
                if(i % pri[j] == 0) {
                    phi[i * pri[j]] = phi[i] * pri[j];
                    break;
                }
                phi[i * pri[j]] = phi[i] * (pri[j] - 1);
            }
        }
        
        for(int i = 1; i <= Maxn; i++) {
            ll now = phi[i] * i / 2;
            if(i == 1) now = 1LL;
            for(int j = i; j <= Maxn; j += i)
                h[j] += now;
        }
    }
    
    int main() {
        sieve();
        for(read(testCase); testCase--; ) {
            int n; read(n);
            printf("%lld
    ", 1LL * n * h[n]);
        }
        return 0;
    }
    View Code

    ———————————————————————————————————————————————————

    upd:

    去看了一下题解,发现其实可以线性筛$h(i) $,感觉很神仙。

    下文中的$h(d) = sum_{t | d} phi (t) * t$

    因为$phi (t)$和$t = N(t)$都是积性函数,所以$phi (t) * t$也是积性函数,那么$h(i)$就相当于$phi(i) * i$与$1$的卷积,所以$h(i)$也是积性函数,可以线性筛。

      $h(p) = (p - 1) * p + 1 = p^2 - p + 1$

      $h(p^k) = h(p^k) = sum_{i = 0}^{k}p^i * phi (p^i) = p^2sum_{i = 0}^{k - 1}p^i * phi (p^i) - p + 1$

    因为$phi (p) = p - 1$,而$phi (p^k) = phi (p^{k - 1}) * p = (p - 1) * p^{k - 1}$,所以相当于多乘了一个$p$,把它减掉,然后加上第一项$1$。

    最后算答案的时候注意到这时候$phi (1)$是取$2$的,所以最后输出$frac{(h(n) + 1)}{2}$。

    时间复杂度$O(MaxN + T)$。

    不想实现。

  • 相关阅读:
    jquery ajax get 数组参数
    xcopy中文文件名,中文件目录乱码问题
    小程序使用wxParse插件解析html标签图片间距问题
    30分钟彻底弄懂flex布局
    abp ueditor 多图以及文件无法上传
    Lubuntu 18.04 自动登录
    树莓派虚拟环境手动安装HA
    ESP-01S刷ESPEasy固件,接入HA
    百度TTS的来由
    Pi 3B+编译安装python3.6.8
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9687956.html
Copyright © 2011-2022 走看看