0*01 位运算
补码
- 在补码下每个数值都有唯一的表示方式
- 发生算数溢出时,32位无符号整数相当于自动对2^32取模
- 0*3F 3F 3F 3F 满足一下两个条件
- 整数的两倍不超过int能表示的最大整数
- 整数的每个字节都是相同的
移位运算
左移
在二进制下把数字同时向左移动,低位以0填充,高位越界后舍弃
\[1<<n=2^n, n<<1=2n \]右移
在二进制下把数字同时向右移动,高位以符号位填充,低位越界后舍弃
\[n>>1=Floor(n/2.0) \]例题
-
求ab%p的值,1<=a,b,p<=109
枚举二进制下每位,没了……
#include<bits/stdc++.h>//a^b%p using namespace std; int a,b,p; int power(){ int ans=1%p; for(;b;b>>=1){ //取遍所有数位 if(b&1) ans=(long long)ans*a%p; //取当前最后一位 a=(long long)a*a%p; } return ans; } int main(){ scanf("%d%d%d",&a,&b,&p); printf("%d",power()); return 0; }
-
求a*b%p的值,1<=a,b,p<=10^18
更神奇的算法……时间复杂度O(n)
#include<bits/stdc++.h> //时间复杂度O(n)的神奇算法 a*b%p using namespace std; typedef unsigned long long ull; ull a,b,p; ull mul(){ a%=p,b%=p; ull c=(long double)a*b/p; ull x=a*b,y=c*p; long long ans=(long long)(x%p)-(long long )(y%p ); if(ans<0) ans+=p; return ans; } int main(){ scanf("%lld %lld %lld",&a,&b,&p); printf("%lld",mul()); return 0; }