【欧拉函数】BZOJ2190-[SDOI2012]longge的数学问题
【题目大意】
求出∑gcd(i, N)(1<=i <=N)。
【思路】
对于x=ak,y=bk,若gcd(a,b)=1则必有gcd(x,y)=1。枚举N的所有因数,∑gcd(i, N)=∑(φ(N/k)*k)(k|N)。
*N的因数与必须在n^(1/2)时间内求出,否则会TLE。
【代码】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 /*注意数据范围*/ 8 const int MAXN=10010; 9 ll n; 10 ll factor[MAXN]; 11 12 void get_factor() 13 /*必须在n^(1/2)时间以内求出所有的质因数,否则会TE*/ 14 { 15 memset(factor,0,sizeof(factor)); 16 ll i; 17 for (i=1;i*i<n;i++) 18 { 19 if (n%i==0) 20 { 21 factor[++factor[0]]=i; 22 factor[++factor[0]]=n/i; 23 } 24 } 25 if (i*i==n) factor[++factor[0]]=i; 26 } 27 28 ll eular(ll k) 29 { 30 ll res=k; 31 for (ll p=2;p*p<=k;p++) 32 { 33 if (k%p==0) 34 { 35 res=res-res/p; 36 while (k%p==0) k/=p; 37 } 38 } 39 if (k>1) res=res-res/k; 40 /*主意k可能大于0,必须要再减去*/ 41 return res; 42 } 43 44 void init() 45 { 46 scanf("%d",&n); 47 } 48 49 ll get_ans() 50 { 51 ll result=0; 52 for (ll i=1;i<=factor[0];i++) 53 result+=eular(n/factor[i])*factor[i]; 54 return result; 55 } 56 57 int main() 58 { 59 init(); 60 get_factor(); 61 cout<<get_ans()<<endl; 62 return 0; 63 }