BZOJ-2705: [SDOI2012]Longge的問題 (歐拉函數)
阿新 • • 發佈:2017-11-04
soft input while arc 打開 bbs amp %20 set
Submit: 3313 Solved: 2072
[Submit][Status][Discuss]
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
6Sample Output
15HINT
【數據範圍】
對於60%的數據,0<N<=2^16。
對於100%的數據,0<N<=2^32。
Source
round1 day1
這題是孬孬昨天跟我裝逼時考我的一道題,當時隨便口胡了一下,然後孬孬說要用莫比烏斯反演???【黑人問號.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即可qwq1 #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 returnan; 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 }
BZOJ-2705: [SDOI2012]Longge的問題 (歐拉函數)