生活随笔
收集整理的這篇文章主要介紹了
数论 欧拉函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數論 歐拉函數
就是對于一個正整數n,小于n且和n互質的正整數(包括1)的個數,記作φ(n) 。
歐拉函數的通式:φ(n)=n*(1-1/p1)(1-1/p2)(1-1/p3)*(1-1/p4)……(1-1/pn)
其中p1, p2……pn為n的所有質因數,n是不為0的整數。φ(1)=1(唯一和1互質的數就是1本身)。
代碼實現如下:
sum
=n
;for(i
=2;i
<=n
/i
;i
++){if(n
%i
==0){sum
=sum
/i
*(i
-1);while(n
%i
==0)n
/=i
;}}if(n
>1)sum
=sum
/n
*(n
-1);
當然,在計算機中歐拉函數常用的還有歐拉打表:(就和素數打表性質差不多)
代碼實現如下:
void init()
{int i
,j
,z
;for(i
=0;i
<maxx
;i
++){s
[i
]=i
;}for(i
=2;i
<maxx
;i
++){if(s
[i
]==i
){for(j
=i
;j
<maxx
;j
+=i
){s
[j
]=s
[j
]/i
*(i
-1);}}}for(i
=2;i
<maxx
;i
++){s
[i
]=s
[i
-1]+s
[i
]*s
[i
];}
}
其中最后一個for循環是求歐拉數組的前綴和
例題一:題目鏈接
題意:給你一個數n,請求出該數的歐拉值。
也就是運用模板一
代碼:
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std
;
int main()
{int i
,j
,z
,n
,sum
;while(~scanf("%d",&n
)){if(n
==0)break;sum
=n
;for(i
=2;i
<=n
/i
;i
++){if(n
%i
==0){sum
=sum
/i
*(i
-1);while(n
%i
==0)n
/=i
;}}if(n
>1)sum
=sum
/n
*(n
-1);printf("%d\n",sum
);}return 0;
}
例題二:題目鏈接
題意:給你兩個數a和b,請求出a到b之間所有歐拉值之和;
也就是進行歐拉打表
要注意,本題數據比較大,要開unsigned long long。
代碼:
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std
;
typedef unsigned long long ll
;
const int maxx
=5000010;
ll s
[maxx
];
void init()
{int i
,j
,z
;for(i
=0;i
<maxx
;i
++){s
[i
]=i
;}for(i
=2;i
<maxx
;i
++){if(s
[i
]==i
){for(j
=i
;j
<maxx
;j
+=i
){s
[j
]=s
[j
]/i
*(i
-1);}}}for(i
=2;i
<maxx
;i
++){s
[i
]=s
[i
-1]+s
[i
]*s
[i
];}
}
int main()
{int i
,j
,z
,k
=0,t
,a
,b
;init();scanf("%d",&t
);while(t
--){k
++;scanf("%d%d",&a
,&b
);ll num
=s
[b
]-s
[a
-1];printf("Case %d: %llu\n",k
,num
);}return 0;
}
總結
以上是生活随笔為你收集整理的数论 欧拉函数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。