2705: [SDOI2012]Longge的问题
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 3313 Solved: 2072
[Submit][Status][Discuss]
Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
Source
这题是孬孬昨天跟我装逼时考我的一道题,当时随便口胡了一下,然后孬孬说要用莫比乌斯反演???【黑人问号.jpg】
今天偶遇了原题,迫不及待的打开题解,想看看莫比乌斯反演是什么玩意,结果点开一看……mdzz这不就是我昨天口胡的那个方法嘛……
然后突然惊悚,貌似今天再想一次的话不一定还能想到正解?(laj还需多加训练!)
我们逆着想一下,求∑gcd(i, N)(1<=i <=N),思考一个数xi可能为哪些数与n的gcd? 不难想到因为是gcd所以这些数/xi后与n/xi是互质的,这就转化为n/xi范围内有多少个数与n/xi互质的问题,这是欧拉函数,∴就相当于求∑xi*phi(n/xi) 不能把phi表全打出来,对于每个n/xi 单独求一遍phi即可qwq
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 LL n,ans; 5 LL eular(LL x){ 6 LL i,an=x; 7 for (i=2;i*i<=x;i++) 8 if (x%i==0){ 9 an=an/i*(i-1); 10 while (x%i==0) x/=i; 11 } 12 if (x!=1) an=an/x*(x-1); 13 return an; 14 } 15 int main(){ 16 freopen ("question.in","r",stdin);freopen ("question.out","w",stdout); 17 int i,j; 18 scanf("%lld",&n); 19 for (i=1;i*i<n;i++) 20 if (n%i==0) 21 ans+=i*eular(n/i)+n/i*eular(i); 22 if (i*i==n) ans+=i*eular(i); 23 printf("%lld",ans); 24 return 0; 25 }
未来是什么样,未来会发生什么,谁也不知道。
但是我知道,
起码从今天开始努力,
肯定比从明天开始努力,
要快一天实现梦想。
千里之行,始于足下! ——《那年那兔那些事儿》