欧拉定理,欧拉函数
来源:互联网 发布:双十一淘宝客服催单 编辑:程序博客网 时间:2024/04/28 08:14
欧拉函数:ϕ (n) = 1...n中与n互质的数的个数;其中,令n = a1^x1 * a2^x2* .....*ak^xk
则ϕ (n) = n*(1-1/a1)*(1-1/a2)*.....*(1-1/ak);
欧拉定理:若a和n互质,则a^ϕ(n)≡1(mod n);若n为质数,则有a^(n-1)≡1(mod n);
求欧拉函数的值
ll oula(ll n) { ll i,res=1; for(i=2;i*i<=n;i++) { if(n%i==0) { n=n/i; res=res*(i-1); while(n%i==0) { n=n/i; res=res*i; } } if(n==1) break; } if(n>1) res=res*(n-1); return res; }
质因数分解求欧拉函数值,降低时间复杂度;
int prime[MAX],mark[MAX],cnt; void Prime(){ memset(mark,0,sizeof(mark)); cnt = 0; for (int i=2; i< MAX; i++){ if (!mark[i]) prime[cnt++] = i; for (int j=0; j<cnt && prime[j]*i <= MAX; j++){ mark[i*prime[j]] = 1; if (i % prime[j] == 0) break; } } }int oula(int x) { int res=x; for(int i=0; i<cnt&&prime[i]*prime[i]<=x; i++) { if(x%prime[i]==0) { res=res/prime[i]*(prime[i]-1); while(x%prime[i]==0) { x/=prime[i]; } } } if(x>1) res=res/x*(x-1); return res; }
筛选法求前n个数的欧拉函数值,打表法
int a[MAX];void oula(int n){memset(a,0,sizeof(a));a[1] = 1;for (int i=2; i<=n; i++){if (!a[i]){for (int j = i; j<=n; j += i){if (!a[j]) a[j] = j;a[j] = a[j] / i * (i-1);}}}}
欧拉函数,打表法模板题 poj2478
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<climits>#include<cctype>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<map>#include<set>#include<string>#include<stack>#define ll long long#define MAX 1000010#define eps 1e-8#define INF INT_MAXusing namespace std;int a[MAX+10];void oula(int n){memset(a,0,sizeof(a));a[1] = 1;for (int i=2; i<=n; i++){if (!a[i]){for (int j = i; j<=n; j += i){if (!a[j]) a[j] = j;a[j] = a[j] / i * (i-1);}}}}int main(){int n;oula(MAX);while (scanf("%d",&n) && n != 0){ll ans = 0;for (int i=2; i<=n; i++) ans += a[i];printf("%lld\n",ans);}return 0;}
利用欧拉定理求高阶幂(a^b^c^d^.....mod P)的模;
由欧拉定理的a^φ(n) = 1(mod n),所以a^b^c^d... mod( P) = a^(b^c^d.....mod(φ(P))) mod (P) = a^(b^(c^d....mod(φ(φ(P))))mod(φ(n)))mod (P)
ll mod_mul(ll a, ll b, ll N) { ll ret = 0; while (b) { if (b & 1) ret = (ret + a) % N; a = 2 * a % N; b >>= 1; } return ret; } ll mod_pow(ll x, ll n, ll N) { ll ret = 1; x %= N; while (n) { if (n & 1) ret = mod_mul(ret, x, N); x = mod_mul(x, x, N); n >>= 1; } return ret; } ll oula(ll n) { ll i,res=1; for(i=2;i*i<=n;i++) { if(n%i==0) { n=n/i; res=res*(i-1); while(n%i==0) { n=n/i; res=res*i; } } if(n==1) break; } if(n>1) res=res*(n-1); return res; } ll x[MAX];stack<ll>S;ll High_pow(ll p, ll n){for (ll i = 1; i<n; i++){S.push(p);p = oula(p);}for (ll i = n-2; i>=0; i--){p = S.top();S.pop();x[i] = mod_pow(x[i],x[i+1],p);}return x[0];}
纯粹的欧拉公式题目 poj2407
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<climits>#include<cctype>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<map>#include<set>#include<string>#include<set>#define ll long long#define MAX 1000010#define eps 1e-6#define INF INT_MAXusing namespace std;int prime[MAX],vis[MAX],a[MAX];int main(){memset(vis,0,sizeof(vis));int cnt = 0;for (int i=2; i<MAX; i++){if (!vis[i]){prime[cnt++] = i;} for (int j=0; j<cnt && prime[j]*i < MAX; j++){vis[prime[j]*i] = 1;if (i % prime[j] == 0) break;}}int n,c;while (scanf("%d",&n) && n != 0){c = 0;double ans = n;for (int i=0; prime[i] <= n; i++){if (n % prime[i] == 0){a[c++] = prime[i];while (n % prime[i] == 0) n /= prime[i];}}//for (int i=0; i<c; i++) printf("%d ",a[i]); printf("\n"); for (int i=0; i<c; i++)ans = ans*(1.0 - 1.0 / a[i]);printf("%d\n",(int)(ans+eps));}return 0;}
poj3696欧拉定理的应用,以及熟悉模算术运算;
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<climits>#include<cctype>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<map>#include<set>#include<stack>#include<string>#define ll long long#define MAX 1000000#define INF INT_MAX#define eps 1e-8using namespace std;ll N;ll gcd(ll a, ll b){ if (b == 0) return a; return gcd(b, a%b);}ll mod_mul(ll a, ll b) //模N下的乘法运算 { long long ret = 0; while (b) { if (b & 1) ret = (ret + a) % N; a = 2 * a % N; b >>= 1; } return ret;}ll mod_pow(ll x, ll n) //模N下的幂运算 { long long ret = 1; x %= N; while (n) { if (n & 1) ret = mod_mul(ret, x); x = mod_mul(x, x); n >>= 1; } return ret;}ll oula(ll n) //求n的欧拉函数值 { ll i,res=1; for(i=2;i*i<=n;i++) { if(n%i==0) { n=n/i; res=res*(i-1); while(n%i==0) { n=n/i; res=res*i; } } if(n==1) break; } if(n>1) res=res*(n-1); return res; } ll a[MAX],cnt;void split(ll n){ //n因式分解 ll m = (ll)sqrt(n+0.5); cnt = 0; for (ll i=1; i<=m; i++){ if (n % i == 0){ a[cnt++] = i; a[cnt++] = n / i; } }}int main(){ ll L,cas = 0; while (scanf("%lld",&L) && L > 0){ cas++; N = 9*L / gcd(9*L,8); if (gcd(10,N) > 1){ printf("Case %lld: %lld\n",cas,0LL); continue; } ll n = oula(N); split(n); sort(a,a+cnt); for (int i=0; i<cnt; i++){ if ( mod_pow(10,a[i]) == 1){ printf("Case %lld: %lld\n",cas,a[i]); break; } } } return 0;}
大致解题思路:
最终答案为x个8,则可以表示为(10^x-1)*(8/9),则有(10^x-1)*(8/9) = 0(mod L),化简得到10^x = 1(mod(9*L/gcd(9*L,8));
则题目变成一个离散对数问题:
若gcd(10,n) != 1 则无解,否则有欧拉定理的10^ϕ (n) = 1mod(n),即至少会存在一个解
又因为10^x = 1(mod n)成立的最小x是ϕ (n)的约数,所以从小到大枚举约数求解。
0 0
- 欧拉函数与欧拉定理
- 欧拉函数与欧拉定理
- 欧拉函数&&欧拉定理
- 欧拉定理,欧拉函数
- 欧拉函数与欧拉定理
- 欧拉函数/欧拉定理
- 欧拉函数和欧拉定理
- 欧拉函数,欧拉定理模板
- POJ3696【欧拉函数+欧拉定理】
- 欧拉函数与欧拉定理
- 欧拉定理 和 欧拉函数
- 欧拉函数与欧拉定理
- 欧拉函数与欧拉定理
- 欧拉函数及定理
- 欧拉定理与函数
- 欧拉函数、欧拉定理、费马小定理
- 欧拉函数、费马定理、欧拉定理
- 原根,欧拉函数,欧拉定理,费马小定理
- HDUJ 1753 大明A+B
- MySQL List分区(三)
- Ext实现滚动条一直处于底部的方法
- 获得打印cocos2dx游戏中左下角的fps值
- ActionContext和ServletActionContext
- 欧拉定理,欧拉函数
- HttpLuaModule文档
- poj 3294 后缀数组求至少在k个串中出现的公共子串
- TCP keep-alive的原理与使用
- poj2255- Tree Recovery(二叉树)
- Mule ESB企业版本和社区版本数据源区别
- java生成密钥对,及对数据进行加密、解密、签名、验签
- 求数组中的最大值
- i have an idea