GCD SUM
Published on 2022-04-30 15:02 in 分类: 洛谷 , 数学 with lviy_ptilopsis^^
分类: 洛谷 , 数学

GCD SUM

    P2398 GCD SUM

     

    解法1. 筛出来欧拉数后暴力搜 80分(实在卡不过去最后俩点了)

    复制代码
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    typedef long long LL;
    int primes[N], cnt;
    bool st[N];
    int phi[N];
    LL temp;
    bool fuck[N];
    
    inline void get_primes(int n) //phi数组
    {
    //    phi[1] = 1;
        for(int i = 2; i <= n; i++)
        {
            if(!st[i])
            {
                primes[cnt++] = i;
                phi[i] = i - 1;
            }
            
            for(int j = 0; primes[j] * i <= n; j++)
            {
                st[primes[j] * i] = true;
                
                if(i % primes[j] == 0)
                {
                    phi[primes[j] * i] = phi[i] * primes[j];
                    break;
                }
                phi[primes[j] * i] = phi[i] * (primes[j] - 1);
            }
        }
    }
    
    inline void dfs(int u, int v, int rem)
    {
        if(u == 1 || v >= cnt) return;
        
        for(int i = v; i < cnt && primes[i] <= u / 2; i++) //问题就是 如果剩下个数咋办。
            if(u % primes[i] == 0 && !fuck[u % primes[i]]) dfs(u / primes[i], v, rem);
        
    //    cout<<u<<endl;
        if(!fuck[u]) temp += phi[u] * (rem / u), fuck[u] = true;
    }
    
    signed main()
    {
        //预处理出来了质数数组,然后质数试除 时间复杂度1e5 * ln1e5 互质数直接欧拉函数处理 如果该数为质数便直接不用了
        int n;
        cin>>n;
        get_primes(n);
        LL ans = 0;//1LL * n * (n + 1) / 2; 
        for(register int i = 1; i <= n; i++) //ans加上每个数的互质个数(因为gcd互质数=1) 然后加上每个数的约数之和)
        {
            if(!st[i])
            {
                temp += phi[i];
                continue;
            }
            memset(fuck, false, sizeof fuck);
            dfs(i, 0, i);    
        }
        ans += 2 * temp;
        ans += 1LL * n * (n + 1) / 2;
        
        cout<<ans<<endl;
    }
    复制代码

    解法2: 筛出来欧拉函数后发现每个欧拉数被用了sum(1 ~ n/i)次 直接遍历1 ~ n 复杂度O(n) 100分  ''' 解法3:筛出数后数论分块 时间复杂度O(q√n) q是查询次数 代码等学会了后补TAT

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    typedef long long LL;
    int primes[N], cnt;
    bool st[N];
    int phi[N];
    LL temp;
    bool fuck[N];
     
    inline void get_primes(int n) //phi数组
    {
    //  phi[1] = 1;
        for(int i = 2; i <= n; i++)
        {
            if(!st[i])
            {
                primes[cnt++] = i;
                phi[i] = i - 1;
            }
             
            for(int j = 0; primes[j] * i <= n; j++)
            {
                st[primes[j] * i] = true;
                 
                if(i % primes[j] == 0)
                {
                    phi[primes[j] * i] = phi[i] * primes[j];
                    break;
                }
                phi[primes[j] * i] = phi[i] * (primes[j] - 1);
            }
        }
    }
     
    signed main()
    {
        //预处理出来了质数数组,然后质数试除 时间复杂度1e5 * ln1e5 互质数直接欧拉函数处理 如果该数为质数便直接不用了
        int n;
        cin>>n;
        get_primes(n);
        LL ans = 0;//1LL * n * (n + 1) / 2;
        for(register int i = 1; i <= n; i++) //ans加上每个数的互质个数(因为gcd互质数=1) 然后加上每个数的约数之和)
        {
            int r = n / i;
            temp += 1LL * phi[i] * r * (r + 1) / 2;
        }
        ans += 2 * temp;
        ans += 1LL * n * (n + 1) / 2;
         
        cout<<ans<<endl;
    }<br><br><br><br><br>

    作者:@lviy_ptilopsis_
    本文为作者原创,转载请注明出处:https://www.cnblogs.com/lviy/p/16210235.html

    posted @   lviy_ptilopsis^^  阅读(44)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
    · 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
    · Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
    · 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
    · 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
    点击右上角即可分享
    微信分享提示