一两句话小技巧
# 一两句话小技巧
# 二进制枚举子集
int S = 11; // 1011b
for(int x=S; x>0; x=(x-1) & S) // do something
// 1. x = 1011 2. x = 1010 3. x = 1001
// 4. x = 1000 5. x = 0011 6. x = 0010
// 7. x = 0001 8. x = 0000
1
2
3
4
5
2
3
4
5
# 求余快速乘
当两个long long
相乘会溢出,又不能用__int128_t
时使用。
当mod
过大时可能出现精度问题。
不使用四舍五入
ll mul_mod(ll a, ll b, ll mod){
return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
}
1
2
3
2
3
使用四舍五入
ll mul_mod(ll a, ll b, ll mod){
ll c = a*b-(ll)((long double)a/mod*b + 0.5)*mod;
return c<0?c+mod:c;
}
1
2
3
4
2
3
4
原理:
令,最终结果为,明显a*b
与d*p
都可能会溢出(即对取模),但他们的差值一定在long long
的范围内(差值的绝对值小于)。
上次更新: 2021/02/24, 03:37:30