位运算

本文介绍了位运算中的按位与和位异或操作的应用技巧,包括判断奇偶性、检查2的幂、快速幂计算、求子集以及利用位异或进行数据处理和数值交换等。同时提供了具体的代码示例,帮助读者更好地理解和掌握这些位运算技巧。

按位与:

judge odd or even number   n为任意整数

if(n&1) n is odd;

②判断一个数是否是2的N次方

2,4,8,16这样的数转化成二进制是10,100,1000,10000。

  如果X减去1后(低一位并且二进制的每一位都是1),这个数与X做与运算,答案若是0,则X是2的N次方。

  所以答案是:!(X&(X-1))

③快速幂(poj3070 Fibonacci

其实就是用到了把十进制转化成二进制的方法(每次都除以2,被除数是奇数时对应的余数为1,此时就可以让base×2^i,无论是奇数还是偶数,base*=base这一步,base*base==base^2,下一步再乘,就是base^2*base^2==base^4,然后同理  base^4*base4=base^8

base-->base^2-->base^4-->base^8-->base^16-->base^32.......指数正是 2^i 啊

  
  
  

int poww(int a,int b){
    if(b==0) return 1;
    int ans=1,base=a;
    while(b!=0){
        if(b&1!=0)
          ans*=base;//%;
        base*=base;//%别忘这一步!!!
        b>>=1;
  }
    return ans;
}
//计算(a ^ p) % m (a*b%c=((a%c)*b)%c)   →a^(2^i)%c = ( (a^(2^(i-1))%c) * a^(2^(i-1)))  %c)如下:
__int64 FastM(__int64 a, __int64 p, __int64 m)
{ 
    if (p == 0) return 1;
    __int64  r = a % m;
    __int64  k = 1;
    while (p)
    {
        if ((p & 1)!=0)
        {
            k = (k * r) % m; 
        }
        r = (r * r) % m;
        p >>= 1;
    }
    return k % m;
}


矩阵快速幂:poj 3070代码如下

#include <cstdio>
#include <iostream>

using namespace std;

const int MOD = 10000;

struct matrix
{
	int m[2][2];
};
matrix ans, base;
matrix multi(matrix a, matrix b)
{
	matrix tmp;
	for (int i = 0; i < 2; ++i)
	{
		for (int j = 0; j < 2; ++j)
		{
			tmp.m[i][j] = 0;
			for (int k = 0; k < 2; ++k)
				tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
		}
	}
	return tmp;
}
int fast_mod(int n)  // 求矩阵 base 的  n 次幂 
{
	base.m[0][0] = base.m[0][1] = base.m[1][0] = 1;
	base.m[1][1] = 0;
	ans.m[0][0] = ans.m[1][1] = 1;  // ans 初始化为单位矩阵 
	ans.m[0][1] = ans.m[1][0] = 0;
	while (n)
	{
		if (n & 1)  //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t 
		{
			ans = multi(ans, base);
		}
		base = multi(base, base);
		n >>= 1;
	}
	return ans.m[0][1];
}

int main()
{
	int n;
	while (scanf("%d", &n) && n != -1)
	{
		printf("%d\n", fast_mod(n));
	}
	return 0;
}


④求子集





位异或:

运算法则↓

1、a^b = b^a。

2、(a^b)^c = a^(b^c)。

3、a^b^a = b。

对于一个任意一个数n,它有几个特殊的性质:

1、0^n = n。

2、n^n = 0。



所以如果让ans=0 让他位移或一组数据 比如1,2,3,1,2,3,4

那么结果就是0^1^2^3^1^2^3^4==0^1^1^2^2^3^3^4==0^0^0^0^4(此思想可用于hdu 2095 Find your presents(2) 例子如下)

#include <stdio.h>
int main()
{
    int n,x,ans;
    while(scanf("%d",&n),n)
    {
        ans = 0;
        while(n--)
        {
            scanf("%d",&x);
            ans ^= x;
        }
        printf("%d\n",ans);
    }
    return 0;
}

②用位异或交换两个数,不引入第三个变量

void swap(int &a,int &b)
{
    a ^= b;
    b ^= a;
    a ^= b;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值