我一直沒有更新,緣由不解釋。個人luogu有這一篇,我搬運過來哈。c++
先感謝李煜東老師的辛勤勞動,我是借鑑他的成果。 位運算共有4種,它們是與或非和異或廢話git
十進制的數不能參與運算,在計算機中是二進制,若是直接對其運算就比十進制塊不少。因此說位運算最快,而後是加減,接着是乘除,最慢的是取模,慢的一匹你們先體驗一把位運算,打開手機計算器的科學計數法,而後調成二進制。。。數組
好,與指的是按照二進制位的兩個數字,兩位都是1就是1,不然爲0,或就是按照二進制位兩位有一位是1就爲1,兩個數位都是0纔是0,非就是把每一位都取反,異或是兩位相同爲0,不一樣爲1。須要注意的是兩個數比較時不足位按0計算,直到兩個數位數相同。優化
左移就是直接把每一位都向左移,右移也是這樣的。隨意 來舉個例子5等於二進制下的101(這個確定會啊),左移兩位就是10100(低位是0補足),天然是十進制下的20啦!ui
左移就是乘二右移就是除二,哦咱們好像能夠用這個優化乘二啊!還有更神奇的事情!n<<1就是乘二,n<<3就是乘8啊,那麼加起來不就是乘十了嗎?這真是激動人心的發現 固然同理有的減法也能夠用^來優化,或能夠用來判斷奇數:好比11的二進制是1011,(1011&1)=(1011&0001)=(0001)返回了1! 哇太強了,之後能夠用(x&1)判斷是否是奇數了,若是用x%2的後果就是x不停的減二。。。一直減到剩下1或者0。spa
順便講一下lowbit運算,這個可吊了。lowbit的定義是整數在二進制下最低位的1及其後邊的全部0,lowbit(n)=n&(-n) 這波廢話其實意思是說找到最右的1構成的數,好比lowbit(14)=1110,那麼lowbit(n)就是2啊!這個詳見樹狀數組。code
狀態壓縮就是將一個長度爲m的bool數組換成一個用二進制數存貯的方法。下列是狀態壓縮的經常使用表達式: 1,取出n的第k位 (n>>k)&1 就是把n刪掉幾位或1,簡單吧get
2,取出n的後k位 n&((1<<k)-1) 這個我也不怎麼會it
3.把n的第k位賦1 n|(1<<k) 就是製造一個數是2的k次方纔能和n進行運算啊,同理有 n^(1<<k) 和 n&(~(1<<k))這個是第k位賦0二進制
接下來是位運算實戰!!!大佬勿噴
1,位運算加速快速冪
#define int long long inline int quickpower(int a,int b,int p){ register int ans=1; for (;b;b>>=1){ if (b&1) ans=ans*a%p; a=a*a%p; }return ans; }
2,最短曼哈頓路徑
int f[1<<20][20]; inline int hamilton(int n,int weight[20][20]){ memset(f,0x3fsizeof(f)); f[1][0]=0; for (register int i=1;i<=1<<n;++i) for (register int j=0;j<n;++j) if (i<<j&1) for (register int k=0;k<n;k++) if ((i^1<<j)>>k&1) f[i][j]=min(f[i][j],f[i^1<<j][k]+weight[k][j]); return f[(1<<n)-1][n-1]; }
咱們到了主題,P3901 這道題一開始把我看得一臉懵逼,最後看懂了,原來是要求出是否是每一個數字都不一樣啊!這是個人題解,天然還能優化,再也不細說了。
#include<bits/stdc++.h> using namespace std; int a[100001],n,q; bool b[100001]; inline int read(){ register int x=0; register char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x; } int main(){register bool flag=false; n=read(),q=read(); for (register int i=1;i<=n;i++) a[i]=read(); for (register int i=1,l,r;i<=q;i++){ l=read(),r=read(),flag=false; memset(b,false,sizeof(b)); for (register int j=l;j<=r;j++) if (b[a[j]]){ flag=true,puts("No"); break; } else b[a[j]]=1; if (!flag) puts("Yes"); } return 0; }