• Luogu P2568 GCD


    我们首先发现这样肯定是做不了的,所以我们枚举为(gcd(x,y)=d)(d)

    然后考虑以下的性质:

    (gcd(x,y)=1 Leftrightarrow gcd(px,py)=p(p为素数))

    这个很显然吧,因此当我们枚举素数(d)时只需要计算(x,yin[1,lfloorfrac{n}{d} floor])(gcd(x,y)=1)有序(x,y)对数即可。

    我们假定(x<=y),那么很容易结合欧拉函数的性质得出此时对答案的贡献为(2cdotsum_{i=1}^{lfloorfrac{n}{d} floor}phi(i)-1)

    这个比较显然吧,假定(iin[1,lfloorfrac{n}{d} floor])为较大的那个,所以无序的对数就是(phi(i)),由于有序所以乘2。最后注意一下((1,1))会被计算两次要减去。

    最后给欧拉函数记一个前缀和即可。

    CODE

    #include<cstdio>
    #define RI register int
    using namespace std;
    const int P=1e7;
    int prime[P+5],phi[P+5],cnt,n; long long ans,sum[P+5]; bool vis[P+5];
    inline void resolve(int x)
    {
        vis[1]=phi[1]=1; sum[1]=2; for (RI i=2;i<=n;++i)
        {
            if (!vis[i]) prime[++cnt]=i,phi[i]=i-1;
            for (RI j=1;j<=cnt&&i*prime[j]<=n;++j)
            {
                vis[i*prime[j]]=1; if (i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
                else { phi[i*prime[j]]=phi[i]*prime[j]; break; }
            }
            sum[i]=sum[i-1]+(phi[i]<<1);
        }
    }
    int main()
    {
        RI i; scanf("%d",&n); for (resolve(n),i=1;i<=cnt;++i)
        ans+=sum[n/prime[i]]-1; return printf("%lld",ans),0;
    }
    
  • 相关阅读:
    java开学第一周测试自我感想
    暑假第八周进度报告
    暑假第七周进度报告
    暑假第六周进度报告
    暑假第五周进度报告
    暑假第四周进度报告
    暑假第三周进度报告
    暑假第二周进度报告
    《大道至简》读后感
    暑假第一周进度报告
  • 原文地址:https://www.cnblogs.com/cjjsb/p/9715535.html
Copyright © 2020-2023  润新知