【数论】【筛法求素数】【欧拉函数】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\n",ans);
37     return 0;
38 }

 

转载于:https://www.cnblogs.com/autsky-jadek/p/4067469.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值