天津网络赛---数论分析题)

来源:互联网 发布:惠州惠阳区网络问政 编辑:程序博客网 时间:2024/04/30 14:45
 

HDU4279(2012年天津网络赛---数论分析题)

分类: 数论 170人阅读 评论(0) 收藏 举报

题目:Number


题意: 给出一个f(x),表示不大于x的正整数里,不整除x且跟x有大于1的公约数的数的个数。定义F(x),为不大于x的正整数里,满足f(x)的值为奇数的数的个数。题目就是求这个F(x)。


网上很多方法就是打表找规律,已经谈不上是算法了。

这里我们可以来分析:


不整除x且跟x有大于1的公约数的数的个数 f(x)=x-约数个数-互质数个数+1 。


把x素因子分解,易知x的约数个数为(质数的幂+1)的累乘。所以若要使约数为奇数,充要条件是(质数的幂+1)都为奇

数,即质数的幂都为偶数。所以此时x必然是一个平方数。


综上,x为平方数,其约数个数为奇数;x为非平方数,其约数个数为偶数。


互质数个数,我们有欧拉函数。

这里用到一个结论:欧拉函数在n>2时,值都为偶数。

所以,

当x>2时:

若x为平方数,f(x)=x-奇-偶+1,要使f(x)为奇数,则x必为奇数;

若x为非平方数,f(x)=x-偶-偶+1,要使f(x)为奇数,则x必为偶数。 

当x=1或2时,f(x)=0.


综上,F(x)的值为[3,x]中,奇数平方数+偶数非平方数的个数和,即 偶数个数-偶数^2的个数+奇数^2的个数。

而偶数个数为 x/2-1,-1是为了把2减掉。偶数^2个数为 sqrt(x)/2,奇数^2个数为 ( sqrt(x)-(sqrt(x)/2) )-1,这里-1是为了把1减掉。


所以,化简后,F(x)=x/2-1+(sqrt(x)%2? 0:-1).


[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <string.h>  
  3. #include <stdio.h>  
  4. #include <math.h>  
  5.   
  6. using namespace std;  
  7. typedef long long LL;  
  8.   
  9. LL Solve(LL n)  
  10. {  
  11.     LL ans=0;  
  12.     if(n<6) return 0;  
  13.     ans+=n/2-2;  
  14.     if((LL)sqrt(1.0*n)&1) ans++;  
  15.     return ans;  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     LL a,b,t;  
  21.     cin>>t;  
  22.     while(t--)  
  23.     {  
  24.         cin>>a>>b;  
  25.         cout<<Solve(b)-Solve(a-1)<<endl;  
  26.     }  
  27.     return 0;  
原创粉丝点击