首先我們需要清楚位運算的一些基本知識。
與 a&b
或 a|b
非 ~a
異或 a^b
int 32位
1:0000000...1
2:0000000...10
3:0000000...11
補碼(表示計算機中的負數): ~a+1是a的補碼即(-a)
memset(a,0x3f,sizeof a)//把這個a所佔的全部位元組初始化為0x3f(十六進製制)
0x3f3f3f3f*2 < 0xffffffff //乘2的話不會溢位
1 -> 10 -> 100
1<2^n
n>>x => n/2^x
這是位運算的一些基本知識。通過位運算來進行加減乘除,能夠很大的降低時間複雜度。
有了這些知識點之後我們可以用快速冪來做一道題,如下題所示。
這題需要求出a的b次方,有乙個問題就是資料範圍是a,b,p<=10e9,如果用for迴圈去遍歷相乘的話時間複雜度最壞是10e9,而計算機一般一秒能運算5.0*10e8,所以o(n)的時間複雜度肯定是不行的,這裡我們需要用到快速冪。
舉個例子:
3 7 6
我們知道要求3^7的值需要for迴圈7次,結果是2187
而如果使用快速冪的話是log級別的時間複雜度
因為7的二進位制**是111,我們可以通過二進位制**來乙個個的與3相乘。
即:3^1=3
3^2=9
3^4=81,
最後我們把這三個數相乘的話就能得到3^7的值是2187,實際上我們執行迴圈的次數只有三次,這題讓求mod 6之後的資料我們可以在每次相乘得到結果後%6這樣不會影響最後結果,而且還能防止溢位,因為最後的資料會很大,所以必須不斷乘不斷模,要注意的一點是這個兩個數相乘一次的時候可能會溢位,所以我轉換為了long long型的資料防止溢位,注意下方**注釋。
資料比較小還看不出來什麼,
如果是3 10000 6的話可以自行試一下,會發現只有二十次的相乘。
c++版本:
#include using namespace std;
int main()
cout
#include int main()
printf("%d",res);
return 0;
}這裡說說為什麼要a=a*1ll%p,舉個例子
3 5 2
5:101
3^1=3
3^4=27
1.res=1*3%2=1
a=3*3%2=1
2.a=1*1%2=1
3.res=1*1%2=1
a=1從這裡我們可以發現res儲存的是每次相乘取模之後的結果,對a再進行一次取模運算的話不會影響結果,但是如果不取模的話a會溢位的。(這裡因為題意是取模運算,如果只是普通的相乘的話不要mod啥。直接乘就行。)
下面我們來看第二道題:
這題的資料範圍是a,b,p<=10e8,也就最大是64位的整數,兩個64位的整數相乘能得到乙個128位的整數,如果用高精度演算法的話肯定能做出來,但是這題有乙個mod p,說明我們可以通過快速冪來去算出來。
舉個例子
3 5 7
5二進位制:101
3*1=3
3*4=12
12+3=15
c語言版本:
#include int main()
printf("%lld",res);
return 0;
}
以上就是快速冪了,下面還要說幾個地方。
/*
1.用異或來實現配偶
0,12,3
4,56,7
0^1=1 1^0=1
2^1=3 3^1=2
4^1=5 5^1=4
e[index]
e[index^1]
(在圖論裡挺有用的)
2.lowbit運算
假如有乙個二進位制數,我們想就求出來最右邊的1到末尾的值,
即x=1110001000 =>1000
~x+1=0001111000
(~x+1)&x=1000
所以lowbit運算可以這麼總結
int lowbit(int n)
3.n>>j&1 判斷二進位制第j位是否為1(二進位制)
i-(1<>k&1 把i減去2的j次方之後判斷第k位是否為1
m=1<<20 2的20次方
state|1<
*/
C 位運算詳解
以前收藏過一篇講c 位操作的文章,這次部落格搬家,以前的資料都沒有保留,整理谷歌 管理後台的時候,發現不時的還有有在查詢這篇文章。所以,瘋刀也來弄個簡單的教程,講講位操作的用途和魅力吧。位是資料儲存的最小單位。在 計算機中的二進位制數系統中,位,簡記為b,也稱為位元,每個0或1就是乙個位 bit 我...
delphi and or 位運算詳解
delphi 的按位運算子共有六個 not and or xor shr shl 其中的 not and or xor 也叫邏輯運算子,其實功能都是一樣的,因為不管什麼資料追到底都是 0 和 1 的組合 在 delphi 內嵌彙編中,應該也沒什麼區別 內嵌彙編還在學習中,不太熟 測試下面的例子時,可...
C 位運算詳解
位是資料儲存的最小單位。在 計算機中的二進位制數系統中,位,簡記為b,也稱為位元,每個0或1就是乙個位 bit 我們先來看看位運算操作符 按位與 按位或 按位異或 按位取反 按位右移 按位左移 1 按位與 從概念上來講,就是將參與運算的兩個分量對應的每一位來做邏輯與運算,若兩者都為真 等於1 則結果...