按位与:
①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;
}