位运算
- & 按位与,全1为1。例如5&3-----> 101&11----->1即1
- | 按位或,有1则1。例如5|3-----> 101|11 ---->111即7
- ^按位异或,相同为0,不同为1。例如5^3----->101^11---->110即6
- ~取反运算,0变1,1变0,例如~5—>101—>010即2
- <<左移指令
- >>右移指令
快速幂运算,即模平方重复计算法
为什么要有快速幂运算,因为对于c++来说,pow函数在函数库中的定义之中是通过连续相乘得到的结果,那么对于一些小的幂来说,计算确实很快,但是当幂达到1e8往上这些大的幂来说的话,时间复杂度太大,过于耗时,所以采用了快速幂的算法,来提高运算的速度,对于来说,普通算法要运算次,而采用快速幂算法的话,只需要运算100次,也就是时间复杂度是O(logn),原本的时间复杂度是O(n)级别的;
具体原理:
对于想要求得的一个,我们可以把y化成二级制的科学计数法,也就是,然后对于原式来说,就变成了
- 对于想要求得
- 只需要求
- 也就是只需要求每个,然后对于所有结果相乘即可
怎么求得每一个的结果呢?
我们观察得出,对于二进制的科学计数法来说,要么是0,要么是1,0、1与有关,而又恰好是二进制的位置索引,举个例子:如5,化为二进制101,化为科学计数法:
所以对于来说,我们只需要知道y对应的二进制数,就可以知道a与c的每一个值,也就可以知道每一个结果;
代码实现:
#include <iostream>
using namespace std;
#define ll long long //long long 类型,这里相当于把long long定义了一个别名;
//为什么用longlong类型?因为对于一个快速幂来说,运算的结果很有可能是一个大于int类型所能处理的数
//b代表底数,y代表幂
ll QuickPow(ll b, ll y)
{
//res代表的结果,tmp则是中间变量
ll res = 1, tmp = b;
while (y)
{
//这个地方也就是,从右往左判断二进制位置上是1还是0,1的话就对于结果进行更新;
if (y % 2 == 1)
res *= tmp;
//tmp代表的就是权
tmp *= tmp;
//对于y进行处理,左移一位
y = (y >> 1);
}
//我们最终想要的结果
return res;
}
int main()
{
ll a, b;
cin >> a >> b;
cout << QuickPow(a, b) << endl;
return 0;
}
矩阵快速幂:
和上面的差不多,主要是多了一个矩阵乘法的问题;具体看代码吧
#include <iostream>
using namespace std;
#define ll long long //定义别名
//Maxx是矩阵的最大行数,Maxy则是矩阵的最大列数
const int Maxx = 100;
const int Maxy = 100;
//用结构体来表示矩阵
struct matrix
{
int m[Maxx][Maxy];
};
//矩阵的乘法法则,ax代表a的行数,ay则是a的列数
matrix mul(matrix a, matrix b, int ax, int ay, int by)
{
//结果矩阵
matrix res;
//初始化
for (int i = 0; i < ax; i++)
for (int j = 0; j < by; j++)
res.m[i][j] = 0;
for (int i = 0; i < ax; i++)
{
for (int j = 0; j < by; j++)
{
for (int k = 0; k < ay; k++)
{
res.m[i][j] = res.m[i][j] + a.m[i][k] * b.m[k][j];
}
}
}
return res;
}
//b的n次方,lenb代表着b的行数
matrix QuickPow(matrix b, ll n, int lenb)
{
//res是用来表示结果的
matrix res;
//初始化为单位阵
for (int i = 0; i < lenb; i++)
{
for (int j = 0; j < lenb; j++)
{
if (i == j)
res.m[i][j] = 1;
else
res.m[i][j] = 0;
}
}
//中间变量
matrix tmp=b;
while(n)
{
if(n%2==1) res=mul(res,tmp,lenb,lenb,lenb);
tmp=mul(tmp,tmp,lenb,lenb,lenb);
n=(n>>1);
}
return res;
}
int main()
{
//用于检验
matrix x;
x.m[0][0]=1;
x.m[0][1]=1;
x.m[1][0]=1;
x.m[1][1]=0;
ll n;
cin>>n;
x=QuickPow(x,n,2);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
cout<<x.m[i][j]<<" ";
}
cout<<endl;
}
}
来源:CSDN
作者:亦无凡
链接:https://blog.csdn.net/zmx2473162621/article/details/103918441