自我小整理——位运算

位运算的小整理

备注:以下^符号除程序中均为次方而非异或
1:基础运算符&优先级
加减(+ -)> 移位(<< >>) >比较大小(> < != ==)>位与(&)>异或(cpp ^)>位或(|)
2:memset函数:字节赋值 比如赋值整形 则只能赋值出每8位(2进制位)一样的数(0,0x3f)
3:快速幂:
即将a^b快速计算出的算法 朴素算法下 需要 b次累乘
快速幂 将b写成2进制并分解为(2^ai)形式
由a的(m+n)次方等于a的m次方乘a的n次方 从而进行 log2(b)次累乘解决

#include
using namespace std;
long long qsm(long long ,long long ,long long);
int main()
{
 long long a,b,p,ans;
 cin>>a>>b>>p;
 if (b!=0)
 {
  ans=qsm(a,b,p);
  cout<>1;
 }
 return rans;
}

4:与快速幂类似的64位余数乘法算法
直接乘会爆掉 又不想高精度 就把b二进制分解为2^ai
算a*2^ai的和 每次求和

#include
using namespace std;
long long wc(long long ,long long ,long long);
int main()
{
 long long a,b,p,ans;
 cin>>a>>b>>p;
 ans=wc(a,b,p);
 cout<>1;
 }
 return rans;
}

5:二进制状态压缩
众所周知,一个bool只能表示1 0两个状态,却占用了大量空间!是极大的浪费!相比之下, int类型真是勤俭持家。所以我们不难想到:把长度为n的bool数组转化成0-2^n-1的int, 从而节约时间和空间。
相对应的,为了从转化的int数中直接读取或修改bool数组某项,我们可以用位运算。

操作 对应位运算
取出n的2进制第k位: (n>>k)&1
取出n的2进制0-k-1位 : n&(1<
n的2进制第k位取反 : n^(1<
n的2进制第k位赋值1 : n位或(1<
n的2进制第k位赋值1 : n&(~(1<

例子:最短Hamilton路径:
代码:

#include
#include
using namespace std;
int weigh[30][30];
int f[1<<20][30];
int main()
{
 int i,j,k,n;
 memset(weigh,0,sizeof(weigh));
 memset(f,0x3F,sizeof(f));
 cin>>n;
 for (i=0;i>weigh[i][j];
 }
 f[1][0]=0;
 for (i=0;i<1<>j&1)
  {
   for (k=0;k<=n;k++)
   {
    if (((i^1<>k)&1) 
    if (f[i][j]>f[i^1<

6:在无向图邻接表创建时存储反向边
2k xor 1=2k+1;
2k+1 xor 1=2k;s
从而实现
7:lowbit运算:用来求n在二进制下最低的位
lowbit(n)=n&(~n+1)=n&(-n)
应用于树状数组
另:结合hash可以求出所有1的位
代码如下

#include
#include
using namespace std;
int h[1<<20];
int n,i;
int main()
{
 for (i=0;i<=20;i++) 
 {
  h[1<>n)
 {
  if (n!=0) cout<

另外 2^i 在0<=i<=35时 有 其模37余数为1——36各不相等 从而可以简单化上述hash

#include
#include
using namespace std;
int h[100];
long long n,i;
int main()
{
 for (i=0;i<=35;i++) 
 {
  h[(1ll<>n)
 {
  if (n!=0) cout<

你可能感兴趣的:(自我小整理,位运算)