位运算
来源:互联网 发布:mysql datetime 减法 编辑:程序博客网 时间:2024/06/06 19:53
按位与:
①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;}