zoukankan      html  css  js  c++  java
  • BZOJ2705: [SDOI2012]Longge的问题

    【传送门:BZOJ2705


    简要题意:

      给出一个n,输出Σgcd(i,n)(1<=i<=n)


    题解:

      首先数据范围惊人,然后要加long long!!

      怎么做呢?

      就是先求出n的所有因数

      设a[i]表示n的第i个因子,f[i]为以第i个因子为最大公约数的个数

      然后一般情况下f[i]应该是n/i

      但是我们先来看数据:

      6的因子为:1,2,3,6

      那么f[6]=1是无可非议的

      但是f[3]并不等于2,而是等于1,为什么?

      因为f[6]中已经计算了6,而f[3]中也把6也算了进去,显然是不对的

      那么我们就从后往前求f数组,然后先将f[i]=n/a[i],然后往后面找是否有a[j]%a[i]==0(1<=i<j<=n),如果有,则f[i]-=f[j]

      就好像容斥一样做就可以了

      注意得出来的∑f[i]并不是最终答案,∑f[i]*a[i]才是要的答案


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    LL a[11000];
    LL f[11000];
    int main()
    {
        LL n;
        scanf("%lld",&n);
        LL t=int(double(sqrt(n+1)));
        int len=0;
        memset(f,0,sizeof(f));
        for(LL i=1;i<=t;i++)
        {
            if(n%i==0)
            {
                a[++len]=i;
                if(i*i!=n) a[++len]=n/i;
            }
        }
        f[len]=1;
        sort(a+1,a+len+1);LL ans=a[len];
        for(int i=len-1;i>=1;i--)
        {
            f[i]=n/a[i];
            for(int j=len;j>i;j--)
            {
                if(a[j]%a[i]==0)
                {
                    f[i]-=f[j];
                }
            }
            ans+=f[i]*a[i];
        }
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    python3.7安装pygame
    Jmeter定时器
    弱网测试
    面试心得123
    如何保证测试项目的质量
    LeetCode448-数组中消失的数字
    LeetCode-两数相加
    JVM-Class文件的结构
    leetcode-222完全二叉树的节点个数
    Java虚拟机常用的性能监控工具
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8082513.html
Copyright © 2011-2022 走看看