hdu4279-欧拉函数+约数个数+打表+sqrt()精度问题

来源:互联网 发布:sql里values什么意思 编辑:程序博客网 时间:2024/04/29 17:19

http://acm.hust.edu.cn/vjudge/problem/31861/origin

题目要求 对一个数n, 从【1,n】里去掉其约数,并去掉所有与其互质的数,求剩余数的个数,如果个数为奇数,则 是一个real number

求区间【X,Y】之间的real number数

先是打表发现规律,其实也蛮好证明:

首先 对一个数,与其互质的数肯定是偶数个的(根据欧拉公式可得),其次对于约数,只有平方数的约数才是奇数,其余都是偶数,

如果该数不是平方数

num = n-euler(n)-divisor(n)+1,即偶数的非平方数都是real number ,加1是因为1即使互质也是因子

如果是平方数,则只有奇数的平方数是real number


则如果要求【1,x】有多少个real number ,先求多少个偶数,再减去偶数平方数加奇数平方数

偶数就是n/2, 奇数平方数和偶数平方数,如果sqrt(n)%2,则奇数多一个,否则一样

注意sqrt(1.0*n)会爆,sqrt((double )n) 会爆,只有sqrt((long long doubel )n),才不会

或者 int x=sqrt(n), if (x*x>n) x--;


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;const double pi=acos(-1.0);double eps=0.000001;int num[]= {0,0,0,0,0,0,1,1,2,3}; long long cal1(long long n){    if(n<=4)        return 0;    long long ans=(n-4)/2;    long long tmp=sqrt(n);    if(tmp*tmp>n)        tmp--;    if(tmp%2)        ans++;    return ans;}int main(){    int t;    cin>>t;    while(t--)    {     long long x,y;         scanf("%lld%lld",&x,&y);         long long ret1=cal(x-1);         long long ret2=cal(y);          printf("%lld\n",ret2-ret1);     }    return 0;}



0 0
原创粉丝点击