The Euler function(hdu2824,欧拉函数)
2015-03-22 20:40
155 查看
这道题是欧拉函数基本题
Problem Description
The Euler function phi is an important kind of function in number theory, (n) represents the amount of the numbers which are smaller than n and coprime to n, and this function has a lot of beautiful characteristics. Here comes a very easy question: suppose
you are given a, b, try to calculate (a)+ (a+1)+....+ (b)
Input
There are several test cases. Each line has two integers a, b (2<a<b<3000000).
Output
Output the result of (a)+ (a+1)+....+ (b)
Sample Input
3 100
Sample Output
3042
下面先对欧拉函数做一个简单介绍
1.定义:对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目
2.欧拉函数用φ函数表示。通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。
比如φ(1)=1,φ(12)=12*(1-1/2)*(1-1/3)=4(12=2*2*3,12与1,5,7,11互质)
想法:
题意是告知a与b,要求求出a与b间的每个数的欧拉函数(包括a与b),且a与b很大
首先将1~3000000的质因子求出,将他们存入一个二维数组中,然后根据输入的a与b,对[a,b]中的每个数运用欧拉函数即可
那么如何求那么多数的质因子呢?
可以看我转载的另一篇文章(“求一个数的质因数(1个或n个)”),用的是其中的第二种类型。
其中的第一种类型将会在hdu1286中用到
本题一开始完全借鉴“求一个数的质因数(1个或n个)”中第二种类型,用vector容器做
但出现超内存,因此得知 vector比普通数组要消耗更多内存(预先开得内存很多)
下面是使用vector容器的代码(超内存):
由于vector数组消耗过多内存,随后将其改为普通二维数组
并不再把1~3000000的所有质因子分别存起来后再诶个求欧拉函数,而是将求质因子的过程与求欧拉函数的过程两者结合起来
但答案错误,发现数组必须用__int64,但改后又出现超内存
代码如下(超内存):
最终将vis数组(判断是否访问过)与p数组(存各数的欧拉函数)合并,优化内存,得AC
代码如下(AC):
Problem Description
The Euler function phi is an important kind of function in number theory, (n) represents the amount of the numbers which are smaller than n and coprime to n, and this function has a lot of beautiful characteristics. Here comes a very easy question: suppose
you are given a, b, try to calculate (a)+ (a+1)+....+ (b)
Input
There are several test cases. Each line has two integers a, b (2<a<b<3000000).
Output
Output the result of (a)+ (a+1)+....+ (b)
Sample Input
3 100
Sample Output
3042
下面先对欧拉函数做一个简单介绍
1.定义:对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目
2.欧拉函数用φ函数表示。通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。
比如φ(1)=1,φ(12)=12*(1-1/2)*(1-1/3)=4(12=2*2*3,12与1,5,7,11互质)
想法:
题意是告知a与b,要求求出a与b间的每个数的欧拉函数(包括a与b),且a与b很大
首先将1~3000000的质因子求出,将他们存入一个二维数组中,然后根据输入的a与b,对[a,b]中的每个数运用欧拉函数即可
那么如何求那么多数的质因子呢?
可以看我转载的另一篇文章(“求一个数的质因数(1个或n个)”),用的是其中的第二种类型。
其中的第一种类型将会在hdu1286中用到
本题一开始完全借鉴“求一个数的质因数(1个或n个)”中第二种类型,用vector容器做
但出现超内存,因此得知 vector比普通数组要消耗更多内存(预先开得内存很多)
下面是使用vector容器的代码(超内存):
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> using namespace std; const int M=3000002; vector<int>p[M]; //创建一个vector对象数组(数据类型为int),相当于一个二维数组 int vis[M]; //筛素法中用于标记是否走过 void init() //求1至M各数的质因子 { int i,j; memset(vis,0,sizeof(vis)); for(i=0;i<M;i++) //清空vector数组 { p[i].clear(); } for(i=2;i<M;i++) //筛选素数,筛素法 { if(!vis[i]) //判断是否将i作为质因子 { for(j=i;j<M;j+=i) { vis[j]=1; //不是素数(质数),在下面的循环中不作为质因子,标记一下 p[j].push_back(i); //p[ j ] 具有该质因子i,将i加入p[ j ] 的质因子数组末尾 } } } } int cal(int n) //欧拉函数 { int i,m; m=n; for(i=0;i<(int)p .size();i++) //强制类型转换,用p[i].size()可知道p[ i ] 的质因子数组大小(即p[ i ] 有多少个质因子) { m*=p [i]-1; m/=p [i]; } return m; } int main() { //freopen("in.txt","r",stdin); int a,b,i,sum; init(); while(~scanf("%d%d",&a,&b)) { sum=0; for(i=a;i<=b;i++) { sum+=cal(i); } cout<<sum<<endl; } return 0; }
由于vector数组消耗过多内存,随后将其改为普通二维数组
并不再把1~3000000的所有质因子分别存起来后再诶个求欧拉函数,而是将求质因子的过程与求欧拉函数的过程两者结合起来
但答案错误,发现数组必须用__int64,但改后又出现超内存
代码如下(超内存):
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int M=3000002; __int64 p[M]; //p[i]表示i的欧拉函数 int vis[M]; //筛素法中用于标记是否走过 void init() { __int64 i,j; //WA2,int存不下,必须用__int64 memset(vis,0,sizeof(vis)); for(i=0;i<M;i++) //p[ i ] 的欧拉函数初始时为i { p[i]=i; } for(i=2;i<M;i++) { if(!vis[i]) { for(j=i;j<M;j+=i) //将计算p [ i ] 的质因子与求p [ i ] 的欧拉函数结合,优化内存(这样可以不用二维数组,仅用一维即可) { vis[j]=1; p[j]*=i-1; p[j]/=i; } } } } int main() { //freopen("in.txt","r",stdin); int a,b,i; __int64 sum; //WA1,int存不下,必须用__int64 init(); while(~scanf("%d%d",&a,&b)) { sum=0; for(i=a;i<=b;i++) { sum+=p[i]; } cout<<sum<<endl; } return 0; }
最终将vis数组(判断是否访问过)与p数组(存各数的欧拉函数)合并,优化内存,得AC
代码如下(AC):
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int M=3000002; __int64 p[M]; void init() //将计算p[i]的质因子与求p[i]的欧拉函数结合,优化内存 { int i,j; for(i=0;i<M;i++) //p[i]的欧拉函数初始时为i { p[i]=i; } for(i=2;i<M;i++) //将vis数组与p数组合并,解决超内存(筛素法) { if(p[i]==i) //合并后用于判断i是否已经筛过(思路与筛素同),作用相当于vis数组。若i已被筛过,那么p[i]不等于i { for(j=i;j<M;j+=i) { p[j]*=i-1; p[j]/=i; } } } } int main() { //freopen("in.txt","r",stdin); //欧拉函数(借鉴“求质因数(1个或n个)”中第二种方法) int a,b,i; __int64 sum; init(); while(~scanf("%d%d",&a,&b)) { sum=0; for(i=a;i<=b;i++) { sum+=p[i]; } cout<<sum<<endl; } return 0; }
相关文章推荐
- 欧拉函数之HDU2824 The Euler function
- HDU2824 The Euler function(欧拉函数)
- hdu2824 The Euler function (欧拉函数)
- hdu2824 The Euler function 欧拉函数
- HDU2824-The Euler function-筛选法求欧拉函数+求和
- hdu2824 The Euler function 欧拉函数
- hdu2824 The Euler function 欧拉函数模板题
- hdu2824 The Euler function(欧拉函数个数)
- HDU2824 The Euler function 欧拉函数的应用
- hdu 2824 The Euler function 欧拉函数模板题
- hdu2824 The Euler function
- hdoj2824 The Euler function(欧拉函数)
- HDU 2824 The Euler function【欧拉函数入门题】
- HDU-#2824 The Euler function(欧拉函数+筛法)
- hdu 2824 The Euler function(欧拉函数)
- HDU 1787 GCD Again/HDU 2824 The Euler function(欧拉函数模板)
- 【HDU 2824 The Euler function】+ 欧拉函数
- HDU2824 The Euler function
- (hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)
- hdu 2824 The Euler function (欧拉函数)