欧拉函数代码实现及扩展--快速矩阵幂
参见博客:http://www.cnblogs.com/linyujun/p/5194170.html
https://www.cnblogs.com/wudi-accept/p/5667714.html
欧拉函数的定义:
Φ(n)=小于n的数中与n互质的数的数目。
在写代码之前,我们先看一下,欧拉函数的一个性质
对于任意一个正整数,Φ( n ) = n * (1 - 1 / a1) * (1 - 1 / a2) * … * (1 - 1/an)。其中,a1 a2 … an 为所有 n 的质因子
欧拉函数实现代码:
1 int func(int n) 2 { 3 int temp=n; 4 for(int i=2;i*i<=n;i++) 5 { 6 if(n%i==0)//是否是质因数 7 { 8 temp=temp*(i-1)/i; 9 while(n%i==0) 10 { 11 n/=i; 12 } 13 } 14 } 15 if(n>1)temp=temp*(n-1)/n;//如果n!=1,n也是其中一个质因数 16 return temp; 17 }
欧拉函数扩展,求大数快速矩阵幂
题目描述:
给a,b,c三个数字,求a的b次幂对c取余。
数据范围:多组样例循环输入,每一组输入a,b,c (1<=a,c<=10^9,1<=b<=10^1000000)。
输入:
2 2 2
139123 123124121241452124412124 123121
输出:
0
8984
首先知道一个欧拉函数的一个性质:
ab%p==ab%Φ(p)+Φ(p)%p (证明不会,还请大佬留言)
快速矩阵幂算法 代码:
1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 typedef long long ll; 6 char b[1000100]; 7 ll func(ll n)//欧拉函数 8 { 9 ll temp=n; 10 for(int i=2;i*i<=n;i++) 11 { 12 if(n%i==0)//是否是质因数 13 { 14 temp=temp*(i-1)/i; 15 while(n%i==0) 16 { 17 n/=i; 18 } 19 } 20 } 21 if(n>1)temp=temp*(n-1)/n;//如果n!=1,n也是其中一个质因数 22 return temp; 23 } 24 25 ll POW(ll a,ll b,ll p)//快速矩阵幂 26 { 27 ll ans=1; 28 while(b!=0) 29 { 30 if(b%2!=0) 31 { 32 ans=ans*a%p; 33 } 34 b=b>>1; 35 a=a*a%p; 36 } 37 return ans; 38 } 39 40 int main() 41 { 42 ll a,p; 43 while(cin>>a) 44 { 45 scanf("%s%lld",b,&p); 46 ll len = strlen(b); 47 ll oula = func(p); 48 int temp=0; 49 for(ll i=0; i<len; i++){ //降幂 50 temp = (temp*10+b[i]-'0')%oula;//模运算的性质 51 } 52 cout<<POW(a,temp+func(p),p)<<endl; 53 } 54 55 }
【如有侵权,请告知,立即删除】
ab%p=ab%(p−1)%p
ab%p=ab%(p−1)%p
ab%p=ab%(p−1)%p