欧拉函数-LightOJ1007

来源:互联网 发布:岁寒然后知松柏下一句 编辑:程序博客网 时间:2024/06/05 01:10

https://vj.xtuacm.cf/contest/view.action?cid=86#problem/E
这个题目用java大数写的时候TLE,有时候java大数并不一定可以过即使时间复杂度可以

后来用c++高精度写,超内存

最后明白用unsigned long long可以过,在做题时如果超longlong可以用unsigned long long试试,注意unsigned long long的输出方式llu

代码一用一个数组的方式存储,后面算的数会覆盖之前计算的欧拉数,这样节省了空间。

代码二用两个数组存储,比较容易想到,但是容易超内存,代码二的euler只能用int,用其他的会超内存,但是可以通过强制类型转换,这样不会有误差。

代码一:

#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const int MAXN=5000010;unsigned long long euler[MAXN];//unsigned long long c[MAXN];//刚开始使用两个数组超过了内存//如果像这样用两个数组存储会超内存,可以看出每次迭代之后euler数组就用不到,所以可以用一个数组。void init(){    memset(euler,0,sizeof(euler));    euler[1]=1;    for(int i=2; i<MAXN; i++)    {        if(euler[i])continue;        for(int j=i; j<MAXN; j+=i)        {            if(!euler[j])euler[j]=j;            euler[j]=euler[j]/i*(i-1);        }    }}int main(){    init();    euler[1]=0;    for(int i=2;i<MAXN;i++)        euler[i]=(euler[i]*euler[i])+euler[i-1];    int t;    scanf("%d",&t);    for(int i=1; i<=t; i++)    {        int a,b;        scanf("%d %d",&a,&b);        printf("Case %d: %llu\n",i,euler[b]-euler[a-1]);    }    return 0;}

代码二:

#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const int MAXN=5000001;int euler[MAXN];//int不会超内存unsigned long long c[MAXN];void init(){    memset(euler,0,sizeof(euler));    euler[1]=1;    for(int i=2; i<MAXN; i++)    {        if(euler[i])continue;        for(int j=i; j<MAXN; j+=i)        {            if(!euler[j])euler[j]=j;            euler[j]=euler[j]/i*(i-1);        }    }}int main(){    memset(euler,0,sizeof(euler));    memset(c,0,sizeof(c));    init();    c[1]=0;    for(int i=2;i<MAXN;i++)        c[i]=((ll)euler[i]*(ll)euler[i])+c[i-1];    int t;    scanf("%d",&t);    for(int i=1; i<=t; i++)    {        int a,b;        scanf("%d %d",&a,&b);        printf("Case %d: %llu\n",i,c[b]-c[a-1]);    }    return 0;}
原创粉丝点击