首页 > 其他 > 详细

【BZOJ】【2818】Gcd

时间:2015-02-03 19:11:23      阅读:219      评论:0      收藏:0      [点我收藏+]

欧拉函数/莫比乌斯函数

  嗯……跟2910很像的一道题,在上道题的基础上我们很容易就想到先求出gcd(x,y)==1的组,然后再让x*=prime[i],y*=prime[i]这样它们的最大公约数就是prime[i]了……

  当然我们完全没必要这样做……对于每个prime[j],计算在(1,n/prime[j])范围内互质的数的对数,记为f[j],那么答案就等于sigma(f[j])

  f[j]的求法还是和以前一样啦~(sigma φ(i))*2+1  (加一是因为类似 5,5 这样两个质数它俩的GCD也是质数)

 

核心思想在于转化:即把【求(1,n)范围内gcd=prime的对数】转化为【求(1,n/prime)范围内gcd=1的对数】

RE:题面上说是10^7的范围啊……为什么我开10^7的数组就RE了呢……开10^8就过了- -b

另外,最后结果会很大……需要用long long.

 

技术分享
 1 /**************************************************************
 2     Problem: 2818
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:888 ms
 7     Memory:89164 kb
 8 ****************************************************************/
 9  
10 //BZOJ 2818
11 #include<cstdio>
12 #include<cstring>
13 #include<cstdlib>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20 int getint(){
21     int v=0,sign=1; char ch=getchar();
22     while(!isdigit(ch)) {if(ch==-) sign=-1; ch=getchar();}
23     while(isdigit(ch))  {v=v*10+ch-0; ch=getchar();}
24     return v*sign;
25 }
26 /*******************template********************/
27 const int N=10000010;
28 typedef long long LL;
29 int prime[N],phi[N],tot=0;
30 bool check[N];
31 void getphi(int n){
32     F(i,0,n) check[i]=0;
33     phi[1]=0;
34     F(i,2,n){
35         if(!check[i]){
36             prime[tot++]=i;
37             phi[i]=i-1;
38         }
39         rep(j,n){
40             if(i*prime[j]>n) break;
41             check[i*prime[j]]=1;
42             if(i%prime[j]==0){
43                 phi[i*prime[j]]=phi[i]*prime[j];
44                 break;
45             }
46             else phi[i*prime[j]]=phi[i]*(prime[j]-1);
47         }
48     }
49 }
50 int main(){
51     int n=getint();
52     getphi(n);
53     LL ans=0;
54     rep(j,tot){
55         LL temp=0;
56         F(i,1,n/prime[j]) temp+=phi[i];
57         ans+=2*(LL)temp+1;
58     }
59     printf("%lld\n",ans);
60     return 0;
61 }
62 
欧拉函数

莫比乌斯函数版本的不会写……这里@一下iwtwiioi,大家可以去看他的代码……

【BZOJ】【2818】Gcd

原文:http://www.cnblogs.com/Tunix/p/4270780.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!