二分幂/快速幂
二分幂又叫快速幂
它的主要功能是计算 a^b%p (模 p可有可无) 。
时间复杂度为O(logN)
举个例子:不妨设 a=107,b=102,p=1000000007,如果我们求出了 x=a^51%p, 那么 x^2%p就是答案。
那么下面就是求 a^51:我们求出了 x=a^25,那么 x^2*a就是答案
快速幂非递归(循环+位运算)实现:
1 long long ksm(long long a,long long b,long long mod) 2 { 3 long long ans=1; 4 a%=mod; 5 while(b>0) 6 { 7 if(b&1) 8 { 9 ans=ans*a%mod; 10 } 11 b>>=1; 12 a=a*a%mod; 13 } 14 return ans; 15 }
1 快速幂递归实现: 2 int power(int a, int n){ 3 int ans; 4 if(n==0) ans=1; 5 else 6 { ans=power(a*a, n/2); 7 if(n%2==1) ans*=a; 8 } 9 return ans; 10 }
所谓二分求幂,即是将b次幂用二进制表示,当二进制位k位为1时,需要累乘a的2^k次方。
(1)(x+y)%p=(x%p+y%p)%p;
(2)(x-y)%p=((x%p-y%p)%p+p)%p;
(3)x*y%p=((x%p)*(y%p))%p。
http://acm.hdu.edu.cn/showproblem.php?pid=4506
给你n个数字,分别是a1,a2,a3,a4,a5……an,这些数字每过一个单位时间就会改变,假设上一个单位时间的数字为a1’,a2’,a3’……an’,那么这个单位时间的数字a[i] = a[i - 1]’ * K(i == 1的时候a[1] = a[n]’ * K),其中K为给定的系数。
现在的问题就是求第t单位时间的时候这n个数字变成了什么了?由于数字可能会很大,所以只要你输出数字对10^9 + 7取余以后的结果。
输入数据第一行是一个正整数T,表示有T组测试数据;
每组数据有两行,第一行包含输入三个整数n, t, k,其中n代表数字个数,t代表第t个单位时间,k代表系数;第二行输入n个数字ai,代表每个数字开始的时候是多少。
[Technical Specification]
T <= 100
1 <= n <= 10 ^ 4
0 <= t <= 10 ^ 9 其中 t = 0 表示初始状态
1 <= k <= 10 ^ 9
1 <= ai<= 10 ^ 9
将乘系数与移动分开,由于乘的系数为a^b可能很大,所以用long long 和快速幂
1 #include "iostream" 2 #include "cstdio" 3 #include "cmath" 4 using namespace std; 5 long long fun(long long a,long long b) 6 { 7 8 long long sum=1; 9 while(b>0) 10 { 11 if(b&1) 12 { 13 sum=sum*a%1000000007; 14 } 15 a=a*a%1000000007; 16 b>>=1; 17 } 18 return sum; 19 } 20 int main() 21 { 22 23 long long T,t,n,k,a[10000]; 24 cin>>T; 25 int i; 26 while(T--) 27 { 28 cin>>n>>t>>k; 29 long long c=fun(k,t);//快速幂得系数 30 for(i=0;i<n;i++) 31 { 32 cin>>a[i]; 33 a[i]=a[i]*c%1000000007; 34 } 35 t%=n;//减少运算 36 while(t--)//移动 37 { 38 long long x=a[n-1]; 39 for(i=n-1;i>=0;i--) 40 { 41 a[i]=a[i-1]; 42 } 43 a[0]=x; 44 } 45 for(i=0;i<n;i++) 46 { 47 if(i==n-1) 48 { 49 cout<<a[i]<<endl; 50 break; 51 } 52 cout<<a[i]<<' '; 53 } 54 } 55 return 0; 56 }
http://poj.org/problem?id=3070
计算第n个斐波那契数的后四位所表示的整数
输入n 0 ≤ n ≤ 1,000,000,000 输入-1结束
An alternative formula for the Fibonacci sequence is
.
As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by
.
Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:
.
Time Limit: 1000MS Memory Limit: 65536K
1 class matrix 2 { 3 public: 4 int a[2][2]; 5 matrix() 6 { 7 a[0][0]=a[0][1]=a[1][0]=1; 8 a[1][1]=0; 9 } 10 }; 11 matrix multi(matrix a,matrix b)//矩阵的乘法 12 { 13 matrix temp; 14 for(int i=0;i<2;i++) 15 for(int j=0;j<2;j++){ 16 temp.a[i][j]=0; 17 for(int k=0;k<2;k++) 18 temp.a[i][j]+=a.a[i][k]*b.a[k][j]; 19 if(temp.a[i][j]>10000) 20 temp.a[i][j]=temp.a[i][j]%10000; 21 } 22 return temp; 23 } 24 matrix power(int n)///矩阵的n次幂 25 { 26 matrix temp,s; 27 temp.a[0][1]=temp.a[1][0]=0; 28 temp.a[1][1]=1; 29 while(n!=0)///矩阵的快速幂 30 { 31 if(n%2!=0) 32 temp=multi(temp,s); 33 s=multi(s,s); 34 n=n/2; 35 } 36 return temp; 37 } 38 int main() 39 { 40 int n; 41 matrix ans; 42 while(scanf("%d",&n)&&n!=-1){ 43 ans=power(n); 44 printf("%d\n",ans.a[1][0]); 45 } 46 return 0; 47 }
同余运算及其基本性质
如果两个数a和b之差能被m整除,那么我们就说a和b对模数m同余(关于m同余)。
比如,100-60除以8正好除尽,我们就说100和60对于模数8同余。
它的另一层含义就是说,100和60除以8的余数相同。a和b对m同余,
我们记作a≡b(mod m)。比如,刚才的例子可以写成100≡60(mod 8)。
你会发现这种记号到处都在用,比如和数论相关的书中就经常把
a mod 3 = 1写作a≡1(mod 3)。
如果a≡b(mod m),x≡y(mod m),则a+x≡b+y(mod m)
如果a≡b(mod m),x≡y(mod m),则ax≡by(mod m)
如果ac≡bc(mod m),且c和m互质,则a≡b(mod m)