BZOJ-2190(仪仗队)(欧拉函数)
Crawling in process...
Crawling failed
Time Limit:10000MS Memory Limit:265216KB 64bit IO Format:%lld & %llu
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;
}