位運算
- & 按位與,全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;
}
}