標籤:
歐拉函數
瑪雅,我應該先看看JZP的論文的……賈志鵬《線性篩法與積性函數》例題一
這題的做法……仔細想下可以得到:$ans=2*\sum_{a=1}^n\sum_{b=1}^m gcd(a,b)-n*m$
那麼重點就在於算$\sum_{a=1}^n\sum_{b=1}^m gcd(a,b)$這個東西
copy一下JZP的推導過程:
$$ \sum_{a=1}^n \sum_{b=1}^m gcd(a,b)=&\sum_{a=1}^n \sum_{b=1}^m \sum_{d|gcd(a,b)} \varphi(d) $$
$$ = \sum_{a=1}^n \sum_{b=1}^m \sum_{d|a && d|b} \varphi(d) \\ = \sum \varphi(d) \sum_{1 \leq a \leq n && d|a} \sum{1 \leq b \leq m && d|b} 1 \\ = \sum \varphi(d) ( \sum_{1 \leq a \leq n && d|a} 1) * ( \sum_{1 \leq b \leq m && d|b} 1) \\ = \sum \varphi(d) \frac{n}{d} \frac{m}{d} \]
1 /************************************************************** 2 Problem: 2005 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:40 ms 7 Memory:2152 kb 8 ****************************************************************/ 9 10 //BZOJ 200511 #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 typedef long long LL;21 inline int getint(){22 int r=1,v=0; char ch=getchar();23 for(;!isdigit(ch);ch=getchar()) if(ch==‘-‘)r=-1;24 for(; isdigit(ch);ch=getchar()) v=v*10+ch-‘0‘;25 return r*v;26 }27 const int N=1e5+10,INF=~0u>>2;28 /*****************template**********************/29 int phi[N],prime[N],tot,n,m;30 bool check[N];31 void getphi(int n){32 memset(check,0,sizeof check);33 phi[1]=1;34 int tot=0;35 F(i,2,n){36 if(!check[i]){37 prime[++tot]=i;38 phi[i]=i-1;39 }40 F(j,1,tot){41 if(i*prime[j]>n) break;42 check[i*prime[j]]=1;43 if(i%prime[j]==0){44 phi[i*prime[j]]=phi[i]*prime[j];45 break;46 }47 else phi[i*prime[j]]=phi[i]*(prime[j]-1);48 }49 }50 }51 int main(){52 n=getint(); m=getint();53 if (n>m) swap(n,m);54 getphi(N-1);55 LL ans=0;56 F(i,1,n)57 ans+=(LL)phi[i]*(n/i)*(m/i);58 printf("%lld\n",ans*2-(LL)n*m);59 return 0;60 }
View Code
【BZOJ】【2005】【NOI2010】能量採集