zoukankan      html  css  js  c++  java
  • BZOJ-1968-[Ahoi2005]COMMON 约数研究

    Description

    Input

    只有一行一个整数 N(0 < N < 1000000)。

    Output

    只有一行输出,为整数M,即f(1)到f(N)的累加和。

    Sample Input

    3

    Sample Output

    5
     

    题解

    这道题刚开始以为是线性筛

    但是有一种更优的算法

    考虑因子中有因子i的数的数量

     1 //考虑有多少个数是以i为因子的
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 int n,ans;
     5 int main(){
     6     scanf("%d",&n);
     7     for (int i=1;i<=n;i++)
     8         ans+=n/i;
     9     printf("%d
    ",ans);
    10     return 0;
    11 }
    View Code

    这个代码灰常短,也挺好理解的

    Solution2:

    但是如果想不到怎么办

    那就只好强上线性筛了

    这里先说一下

    num[i]表示i的因子个数,Min[i]表示i的最小质因子的次数

    我们可以通过约数个数定理来求一个数的因子个数

    传送门:https://baike.so.com/doc/5806281-6019081.html

    不难发现一个质数的因子个数为2(1和它本身),最小质因子的次数为1

    我们在筛质数的时候判断一下prime[j]是否为i的最小质因子

    如果是

    num[i*prime[j]]等于num[i]/(Min[i]+1)*(Min[i]+2)

    Min[i*prime[j]]等于Min[i]+1   //最小质因子次数+1

    如果不是

    num[i*prime[j]]就等于num[i]*num[prime[j]] //符合积性函数

    Min[i*prime[j]]等于1   //i*prime[j]的最小质因子为prime[j]且只有1次

     1 //线性筛
     2 #include<bits/stdc++.h>
     3 #define N 1000005
     4 using namespace std;
     5 int n,ans,cnt;
     6 int prime[N],num[N],Min[N];
     7 bool flag[N];
     8 int main(){
     9     scanf("%d",&n);
    10     num[1]=1;
    11     for (int i=2;i<=n;i++){
    12         if (!flag[i]){
    13             prime[++cnt]=i;
    14             num[i]=2;
    15             Min[i]=1;
    16         }
    17         for (int j=1;j<=cnt&&i*prime[j]<=n;j++){
    18             flag[i*prime[j]]=true;
    19             if (!(i%prime[j])){
    20                 num[i*prime[j]]=num[i]/(Min[i]+1)*(Min[i]+2);
    21                 Min[i*prime[j]]=Min[i]+1;
    22                 break;
    23             }
    24             num[i*prime[j]]=num[i]*num[prime[j]];
    25             Min[i*prime[j]]=1;
    26         }
    27     }
    28     for (int i=1;i<=n;i++)
    29         ans+=num[i];
    30     printf("%d
    ",ans);
    31     return 0;
    32 } 
    View Code
  • 相关阅读:
    bzoj3224
    [洛谷日报第62期]Splay简易教程 (转载)
    bzoj1588
    codeforces467C
    codeforces616B
    codeforces379C
    codeforces545C
    codeforces285C
    codeforces659C
    快读代码level.2
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7619909.html
Copyright © 2011-2022 走看看