BZOJ-2190(仪仗队)(欧拉函数)

19 篇文章 0 订阅
1 篇文章 0 订阅

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

//注:把体育委员所处点看作原点(0,0)。于是可以发现体育委员可以看到的点(x,y),满足x与y互质,可以利用欧拉函数性质求解。注意:(1,1),(1,0)  (0,1)这三个点比较特殊。

//输出要用%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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值