仪仗队
【題目描述】
儀仗隊是由學生組成的N*N的方陣,為了保證隊伍在行進中整齊劃一,C君會跟在儀仗隊的左后方,根據其視線所及的學生人數來判斷隊伍是否整齊(如下圖)。現在,C君希望你告訴他隊伍整齊時能看到的學生人數。
【輸入描述】
一個數N。
【輸出描述】
一個數,即C君應看到的學生人數。
【輸入樣例】4
【輸出樣例】9
【數據范圍及提示】
對于100%的數據,1 ≤ N ≤ 40000。
?
回放一下那些年,我與數論的舊時光(Euler函數鎮樓!):
源代碼:#include<cstdio> int N,Num(0),Prime[10001]; bool Flag[30001]={0}; void Solve() //歐拉O(n)篩法。 {for (int a=2;a<=N;a++){if (!Flag[a]) //沒有被篩走,質數無疑。Prime[Num++]=a;for (int b=0;b<Num&&a*Prime[b]<=N;b++) //注意范圍。 {Flag[a*Prime[b]]=true;if (!(a%Prime[b])) //肯定就不是最小素因子啦。break;}} } int main() //輸入一個數N,求出2~N之間素數的個數。 {scanf("%d",&N);Solve();printf("%d",Num);return 0; }/*利用了每一個合數必定有1個最小素因子的事實,每個合數被其對應的最小素因子篩去,O(n)無疑。 */?
正解:
源代碼:#include<cstdio> int n,ans(0),Phi[40001]={0}; void Work() {Phi[1]=1;for (int a=2;a<=n;a++)if (!Phi[a]) //質數無疑。for (int b=a;b<=n;b+=a) //由以下式子轉換得來的。 {if (!Phi[b])Phi[b]=b;Phi[b]=Phi[b]/a*(a-1);} } int main() //該算法在O(n)內篩素數的同時求出所有數的歐拉函數。 {scanf("%d",&n);Work();for (int a=1;a<n;a++)ans+=Phi[a];printf("%d",2*ans+1);return 0; }/*設P為質數。需要用到以下幾個性質:(1)φ(P)=P-1;(2)如果i%P=0,則有φ(i*P)=P*φ(i);(并不是完全積性函數)(3)如果i%P≠0,則有φ(i*P)=(P-1)*φ(i);證明如下:(1)P的因數除了1以外只有P;(2)利用歐拉函數通式可證;(3)P為質數,i%P≠0可得i互質,利用歐拉函數的積性可得φ(i*P)=(P-1)*φ(i); */轉載于:https://www.cnblogs.com/Ackermann/p/5806052.html
總結
- 上一篇: SPOJ 3267: DQUERY 树
- 下一篇: 爬取京东商品分类和链接