大佬们常用的无穷大量:
const int inf = 0x3f3f3f3f;
快速判断二进制中有几个1
方法1:
这里涉及一个&的知识点,&是按位与,就是在一位一位的做与运算,
while(n>0) //这一句,当n不等于0的时候循环执行以下循环体,n等于0的变化条件在n>>=1这一句,将n左移一位,这样当n中所有的”1”位都移出时,就跳出循环了
{
if((n&1)==1) //这句逐个通过位与的方式查看当前n最左边的一位是不是1,若是,则n&1=1,c加1用来计数
c++;
n>>=1;
}
return c;//这样循环结束时就能得到所需的1的个数了
需要注意的是循环条件这部分很巧妙,保证当n的右边没有1的时候就不做循环了,可以假设n=1,循环体就只执行一次就跳出了,而不用遍历n的每一位
方法2:
x=x&(x-1)
表达式的意思就是:把x的二进制表示 从低位开始,将遇到的第一个为1的比特位 置0。
例如:
e1:
x = 01001000
x-1 = 01000111
x&(x-1)=01000000
e2:
x = 01001001
x-1 = 01001000
x&(x-1)=01001000
在循环中利用该表达式可以快速的判断一个数的二进制中有多少个1。
int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
x=x&(x-1)还可以快速判断x是不是2^n。当x为unsigned类型的变量,且其值为2的n次幂的时候,结果为零
快速幂取模(防止爆ll)
LL mul(LL a,LL b)
{
LL ans=0;
while(b)
{
if(b&1) ans=(ans+a)%p;
a=(a+a)%p;
b=b>>1;
}
return ans;
}
LL Pow(LL a,LL b)
{
LL result=1;
LL base=a%p;
while(b)
{
if(b&1) result=mul(result,base)%p;
base=mul(base,base)%p;
b=b>>1;
}
return result;
}
参考文章:
https://blog.csdn.net/si444555666777/article/details/82253837?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161287323116780261962447%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161287323116780261962447&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-1-82253837.pc_search_result_cache&utm_term=%25E4%25BA%258C%25E8%25BF%259B%25E5%2588%25B6%25E6%2580%258E%25E4%25B9%2588%25E5%25BF%25AB%25E9%2580%259F%25E5%2588%25A4%25E6%2596%25AD%25E4%25B8%2580%25E4%25B8%25AA%25E6%2595%25B0%25E9%2587%258C%25E6%259C%2589%25E5%2587%25A0%25E4%25B8%25AA%25E4%25B8%2580