第 372 场周赛(位运算技巧,跳表 + 二分,线段树)
class Solution: def findMinimumOperations(self, s1: str, s2: str, s3: str) -> int: cnt = 0 for a, b, c in zip(s1, s2, s3): if not a == b == c: break cnt += 1 if cnt == 0: return -1 mi = min(len(s1), len(s2), len(s3)) return len(s1) + len(s2) + len(s3) - 3 * cnt
class Solution: def minimumSteps(self, s: str) -> int: ans = cnt1 = 0 for c in s: if c == '0': ans += cnt1 else: cnt1 += 1 return ans
class Solution: def maximumXorProduct(self, a: int, b: int, n: int) -> int: if a < b: a, b = b, a mask = (1 << n) - 1 # n个1 ax = a & ~mask # 无法通过mask修改的部分 bx = b & ~mask # 把低位抠出来 a &= mask b &= mask left = a ^ b # 一位为1,一位为0的位 one = mask ^ left # 全为0的位,全部变为1 ax |= one bx |= one if left > 0 and ax == bx: high_bit = 1 << (left.bit_length() - 1) ax |= high_bit left ^= high_bit bx |= left MOD = 10**9 + 7 return ax * bx % MOD
跳表+二分
class Solution { public: const static int N = 50005, M = 17; int f[N][M]; void init(const vector<int> &a, int n) { for(int j = 0; j < M; j ++ ) { for(int i = 1; i <= n - (1 << j) + 1; i ++ ) { if(!j) f[i][j] = a[i - 1]; else { f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]); } } } } int query(int l, int r) { int k = __lg(r - l + 1); return max(f[l][k], f[r - (1 << k) + 1][k]); } vector<int> leftmostBuildingQueries(vector<int>& heights, vector<vector<int>>& queries) { int n = heights.size(), m = queries.size(); init(heights, n); vector<int> res(m); for(int i = 0; i < m; i ++ ) { int l = queries[i][0] + 1, r = queries[i][1] + 1; if(l > r) swap(l, r); if(l == r) res[i] = l - 1; else if(heights[l - 1] < heights[r - 1]) res[i] = r - 1; else { int L = r, R = n + 2; while(L + 1 < R) { int m = (L + R) >> 1; if(query(r + 1, m) > heights[l - 1]) R = m; else L = m; } if(L == n + 1) res[i] = -1; else res[i] = L; } } return res; } };
线段树做法
class Solution { public: vector<int> tr; void build(int u, int l, int r, vector<int> &heights) { if(l == r) { tr[u] = heights[l - 1]; return; } int m = l + r >> 1; build(u << 1, l, m, heights); build(u << 1 | 1, m + 1, r, heights); tr[u] = max(tr[u << 1], tr[u << 1 | 1]); } int query(int u, int l, int r, int L, int v) { if(v >= tr[u]) return 0; if(l == r) return l; int mid = l + r >> 1; if(L <= mid) { int pos = query(u << 1, l, mid, L, v); if(pos > 0) return pos; } return query(u << 1 | 1, mid + 1, r, L, v); } vector<int> leftmostBuildingQueries(vector<int>& heights, vector<vector<int>>& queries) { int n = heights.size(); tr.resize(n * 4); build(1, 1, n, heights); vector<int> ans; for(auto &q: queries) { int i = q[0], j = q[1]; if(i > j) swap(i, j); if(i == j || heights[i] < heights[j]) { ans.push_back(j); } else { int pos = query(1, 1, n, j + 1, heights[i]); ans.push_back(pos - 1); } } return ans; } };