【BZOJ】【2005】【NOI2010】能量采集

欧拉函数


  玛雅,我应该先看看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的推导过程:

$$ \begin{aligned}  \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 and 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) \left\lfloor \frac{n}{d} \right\rfloor \left\lfloor \frac{m}{d} \right\rfloor \end{aligned} $$

 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 2005
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 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

 

posted @ 2015-04-03 17:43  Tunix  阅读(...)  评论(...编辑  收藏