zoukankan      html  css  js  c++  java
  • 【数论】【筛法求素数】【欧拉函数】bzoj2818 Gcd

    gcd(x,y)(1<=x,y<=n)为素数(暂且把(x,y)和(y,x)算一种) 的个数

    <=> gcd(x/k,y/k)=1,k是x的质因数 的个数

    <=> Σφ(x/k) (1<=x<=n,k是x的质因子)

    这样的复杂度无法接受,

    ∴我们可以考虑枚举k,计算Σφ(q/k) (k是n以内的质数,q是n以内k的倍数),即Σ[φ(1)+φ(2)+φ(3)+...+φ(p)] (p=n/k)

    介个phi的前缀和可以预处理粗来。

    但是(x,y)和(y,x)并不同,所以在计算前缀和的时候,对于φ(x) (x≠1),要乘2再累加,即Σ[φ(1)+φ(2)*2+φ(3)*2+...+φ(p)*2] (p=n/k)。

    ∴对每个n以内的素数,我们可以O(1)地得到其对答案的贡献。

    ∴时间复杂度花费在筛素数和预处理phi上,为O(n*log(log(n)))或O(n)[线性筛]。

     1 #include<cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 int phi[10000001],n;
     5 bool unPrime[10000001];
     6 ll ans,sum[10000001];
     7 void Shai_Prime()
     8 {
     9     unPrime[1]=1;
    10     for(ll i=2;i<=n;i++) if(!unPrime[i])
    11       {
    12           ans+=sum[n/i];
    13           for(ll j=i*i;j<=n;j+=i)
    14           unPrime[j]=1;
    15       }
    16 }
    17 void phi_table()
    18 {
    19     phi[1]=1;//规定phi(1)=1; 
    20     for(int i=2;i<=n;i++)
    21       if(!phi[i])//若i是质数(类似筛法的思想) 
    22         for(int j=i;j<=n;j+=i)//i一定是j的质因数 
    23           {
    24             if(!phi[j]) phi[j]=j;
    25             phi[j]=phi[j]/i*(i-1);
    26           }
    27 }
    28 void init_sum()
    29 {
    30     sum[1]=phi[1];
    31     for(int i=2;i<=n;i++) sum[i]=(ll)(phi[i]<<1)+sum[i-1];
    32 }
    33 int main()
    34 {
    35     scanf("%d",&n); phi_table(); init_sum(); Shai_Prime();
    36     printf("%lld
    ",ans);
    37     return 0;
    38 }
  • 相关阅读:
    Pwn-level0
    Pwn-level2
    【php】php从多个数组中取出最大的值
    【算法】php计算数字k在一段数字范围出现的次数
    【算法】php计算出丑数
    【php】php常用函数代码封装(一)数组篇
    【Golang】go语言设计模式
    什么是RPC
    【php】 php获取文件路径中的文件名和文件后缀方法
    【php】php目录路径函数系列
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4067469.html
Copyright © 2011-2022 走看看