2 条题解

  • 6
    @ 2022-6-12 20:15:58

    本体观察数据范围显然不是暴力枚举每一个数字,求它有多少个因子的,如果是这么做的话,时间复杂度是O(nn)O(n\sqrt{n})的。

    考虑对于1n1\sim n中的每一个数字,因子11是每一个数字都会有的,那么因子11的个数就是n/1n/1

    同理22的个数n/2n/2

    所以一个for循环求和即可。

    for (int i = 1; i <= n; i++)
    {
    	ans += n / i;
    }
    

    这么做的时间复杂度是O(n)O(n),已经可以通过本题,考虑进一步优化。

    假如nn2020,那么因子77个数只有22,也就是只有7,147,14这两个有因子77,同时我们发现8,9,108,9,10都是因子个数22的,后续的因子112011\sim 20全都是11,我们开始思考如何省去这部分重复计算,我们目前的研究的因子是ii,也就是找到和它的个数相等的边界jj,其实就是n/(n/i)n/(n/i),例如20/(20/7)20/(20/7),那我们下一个数字直接从20/(20/7)+120/(20/7)+1去枚举,就解决了重复计算,对于重复的只需要统计重复了几次,显然是n/(n/i) i + 1n/(n/i)\ - i\ +\ 1

    for (int i = 1; i <= n; i = j + 1)
    {
    	j = n / (n / i);
    	ans += (j - i + 1) * (n / i);
    }
    
  • 2
    @ 2023-5-14 20:57:23
    #include<iostream>
    #include<cstdio>
    #define re register int
    using namespace std;
    int n,ans;
    int main()
    {
    	scanf("%d",&n);
    	for(re i=1;i<=n;++i)//枚举1--n中因子有i的数的个数
    		ans+=n/i;
    	printf("%d",ans);
    } 
    
    • 1

    信息

    ID
    1825
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    291
    已通过
    130
    上传者