HDU 4135 Co-prime 数论-求素数对

来源:互联网 发布:power point for mac 编辑:程序博客网 时间:2024/05/20 14:14

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4135


题意:从A到B中,有多少个数与n互质。

1、当n>=B时,求出从1~B与n互质的个数 减去 从1~A-1与n互质的个数。

2、当n<B时,p1=(A-1)%n,p2=B%n。求出从1~p1与n互质的个数、从1~p2与n互质的个数。

相减加上中间有多少个n的欧拉函数值及为所求。


AC代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>#include <cfloat>using namespace std;typedef __int64 LL;const int N=1000005;const LL II=1000000007;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);LL n,m,pri[N];LL prime(LL x){    LL i,j,numi=0;    for(i=2;i*i<=x;i++)        if(x%i==0)        {            pri[numi++]=i;            while(x%i==0)                x/=i;        }    if(x>1)        pri[numi++]=x;    return numi;}LL dfs(LL k,LL n)//pri[i]表示n的第i个质因子,0~numi-1{    if(n==0)        return 0;    LL i,j,t,numi;    numi=prime(k);//求质因子,numi表示n的质因子的个数    LL sum=0;    for(i=1;i<(1<<numi);i++)    {        LL temp=1,k=0;        for(j=0;j<numi;j++)            if(i&(1<<j))            {   temp*=pri[j];   k++;    }        if(k&1) sum+=n/temp;        else    sum-=n/temp;    }    return n-sum;}LL euler_phi(LL n)//求欧拉函数n的值{    LL m=sqrt(n+0.5),ans=n,i;    for(i=2;i<=m;i++)        if(n%i==0)        {            ans=ans/i*(i-1);            while(n%i==0)                n/=i;        }    if(n>1)        ans=ans/n*(n-1);    return ans;}int main(){    LL i,j,A,B;    int ci=0,T;    scanf("%d",&T);    while(T--)    {        LL a1,a2;        scanf("%I64d%I64d%I64d",&A,&B,&n);        printf("Case #%d: ",++ci);        if(n>=B)        {            a1=dfs(n,A-1);            a2=dfs(n,B);            printf("%I64d\n",a2-a1);            continue;        }        LL k1=(A-1)/n,k2=B/n;        LL p=euler_phi(n);        LL p1=(A-1)%n,p2=B%n;        a1=dfs(n,p1);        a2=dfs(n,p2);        printf("%I64d\n",a2-a1+(k2-k1)*p);    }    return 0;}


突然发现,不用判断B和n的大小,都用第一种方法计算,

但是我感觉这样会不会越界、超时。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>#include <cfloat>using namespace std;typedef __int64 LL;const int N=100005;const LL II=1000000007;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);LL n,m,pri[N];LL prime(LL x){    LL i,j,numi=0;    for(i=2;i*i<=x;i++)        if(x%i==0)        {            pri[numi++]=i;            while(x%i==0)                x/=i;        }    if(x>1)        pri[numi++]=x;    return numi;}LL dfs(LL k,LL n)//pri[i]表示n的第i个质因子,0~numi-1{    if(n==0)        return 0;    LL i,j,numi;    numi=prime(k);//求质因子,numi表示n的质因子的个数    LL sum=0;    for(i=1;i<(1<<numi);i++)    {        LL temp=1,t=0;        for(j=0;j<numi;j++)            if(i&(1<<j))            {   temp*=pri[j];   t++;    }        if(t&1) sum+=n/temp;        else    sum-=n/temp;    }    return n-sum;}int main(){    LL i,j,A,B;    int ci=0,T;    scanf("%d",&T);    while(T--)    {        LL a1,a2;        scanf("%I64d%I64d%I64d",&A,&B,&n);        printf("Case #%d: ",++ci);        a1=dfs(n,A-1);        a2=dfs(n,B);        printf("%I64d\n",a2-a1);    }    return 0;}




原创粉丝点击