二分幂/快速幂

  二分幂又叫快速幂

它的主要功能是计算 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)

 

posted @ 2017-03-01 23:45  kimsimple  阅读(769)  评论(0编辑  收藏  举报