Description
作爲體育委員,C君負責這次運動會儀仗隊的訓練。儀仗隊是由學生組成的N * N的方陣,爲了保證隊伍在行進中整齊劃一,C君會跟在儀仗隊的左後方,根據其視線所及的學生人數來判斷隊伍是否整齊(如下圖)。
現在,C君希望你告訴他隊伍整齊時能看到的學生人數。
Input
共一個數N。
Output
共一個數,即C君應看到的學生人數。
Sample Input
4
Sample Output
9
Hint
【數據規模和約定】 對於 100% 的數據,1 ≤ N ≤ 40000
//輸出要用%lld,不能用%64d,會PE.
歐拉函數性質:
記;x的歐拉函數值爲 f(x),
則:
,其中p1,p2,p3........pn,爲x的所有質因數,x是正整數。
其他性質:
(1):若n是質數p的k次冪,f(n)=p^k-p^(k-1)=(p-1)*p^(k-1),因爲除了p的倍數外,其他數都和n互質。
(2):若m、n互質,f(m*n)=f(m)*f(n);
(3):當n爲奇數時,f(2*n)=f(n);
(4):若n爲素數,則 f(n)=n-1;
此題在加上素數判斷後,跑了4000毫秒,之前不加素數判斷,跑了10000毫秒。
My solution:
/*2016.3.15*/
#include<stdio.h>
#include<string.h>
int vis[40020];
long long ans;
int n;
void prim()//素數打表
{
int i,j,k;
memset(vis,0,sizeof(vis));
vis[1]=1;
for(i=2;i<40020;i++)
{
for(j=2;j*i<40020;j++)
vis[i*j]=1;
}
return ;
}
long long er(int m)
{
long long i,cnt=m;
if(vis[m])//如果m是素數,m的歐拉函數值爲m-1
{
for(i=2;i<=m;i++)
{
if(m%i==0)//i爲m的質因子,因爲i從2開始,如;不可能有m%4==0,m%6==0等情況的出現 ,當i=2時就已經處理過m了,處理過後的m%2!=0,
//因此更不可能m%4==0,同理m%6==0的情況也不可能出現。只有:當且僅當i爲m的質因子時纔有可能滿足m%i==0
{
cnt-=cnt/i;
while(m%i==0)//這條語句保證i是m的質因子
m/=i;
}
}
return cnt;
}
else
return m-1;
}
int main()
{
long long i,j,k,count;
prim();
while(scanf("%lld",&n)==1)//用%I64d輸出結果,格式錯誤
{
count=0;
if(n==1)//容易忽略,當n=1時,只有自己一個人,看到別人的數目爲0
printf("0\n");
else
{
for(i=1;i<=n-1;i++)
count+=er(i);//求小於i且與i互質的因子的個數 ,然後累加
count*=2;//對角線的上方和下方兩部分,所以乘以2 ,不過(1,1)被加了兩次 ,應減1
count+=1;//(1,0)和(0,1)兩個位置也滿足題意,減1再加2
printf("%lld\n",count);
}
}
return 0;
}