intmypow(int n, int k, int p = MOD){ // 复杂度是 log N int r = 1; for (; k; k >>= 1, n = n * n % p) { if (k & 1) r = r * n % p; } return r; } i64 mysqrt(i64 n){ // 针对 sqrt 无法精确计算 ll 型 i64 ans = sqrt(n); while ((ans + 1) * (ans + 1) <= n) ans++; while (ans * ans > n) ans--; return ans; } intmylcm(int x, int y){ return x / gcd(x, y) * y; }
template <classT> T sign(const T &a){ return a == 0 ? 0 : (a < 0 ? -1 : 1); } template <classT> T floor(const T &a, const T &b){ // 注意大数据计算时会丢失精度 T A = abs(a), B = abs(b); assert(B != 0); returnsign(a) * sign(b) > 0 ? A / B : -(A + B - 1) / B; } template <classT> T ceil(const T &a, const T &b){ // 注意大数据计算时会丢失精度 T A = abs(a), B = abs(b); assert(b != 0); returnsign(a) * sign(b) > 0 ? (A + B - 1) / B : -A / B; }
最大公约数 gcd
欧几里得算法
速度不如内置函数! 以 的复杂度求解最大公约数。与内置函数 __gcd 功能基本相同(支持 )。
1
inlineintmygcd(int a, int b){ return b ? gcd(b, a % b) : a; }
位运算优化
略快于内置函数,用于卡常。
1 2 3 4 5 6 7 8 9 10 11 12 13
LL gcd(LL a, LL b){ // 卡常 gcd!! #define tz __builtin_ctzll if (!a || !b) return a | b; int t = tz(a | b); a >>= tz(a); while (b) { b >>= tz(b); if (a > b) swap(a, b); b -= a; } return a << t; #undef tz }
整数域二分
自己用的
1 2 3 4 5 6 7 8 9
auto l = l, r = r; auto check = [&](auto x)->bool { }; while (l < r) { auto mid = l + r >> 1; if (check(mid))r = mid; else l = mid + 1; }
旧版(无法处理负数情况)
在递增序列 中查找 数中最小的一个(即 或 的后继)
1 2 3 4 5 6 7 8 9
while (l < r) { int mid = (l + r) / 2; if (a[mid] >= x) { r = mid; } else { l = mid + 1; } } return a[l];
在递增序列 中查找 数中最大的一个(即 或 的前驱)
1 2 3 4 5 6 7 8 9
while (l < r) { int mid = (l + r + 1) / 2; if (a[mid] <= x) { l = mid; } else { r = mid - 1; } } return a[l];
新版
或 的后继
1 2 3 4 5 6 7 8 9 10 11
int l = 0, r = 1E8, ans = r; while (l <= r) { int mid = (l + r) / 2; if (judge(mid)) { r = mid - 1; ans = mid; } else { l = mid + 1; } } return ans;
或 的前驱
1 2 3 4 5 6 7 8 9 10 11
int l = 0, r = 1E8, ans = l; while (l <= r) { int mid = (l + r) / 2; if (judge(mid)) { l = mid + 1; ans = mid; } else { r = mid - 1; } } return ans;