【力扣周赛】第 362 场周赛(⭐差分匹配状态压缩DP矩阵快速幂优化DPKMP)

文章目录

  • 竞赛链接
  • Q1:2848. 与车相交的点
    • 解法1——排序后枚举
    • 解法2——差分数组⭐
    • 差分数组相关题目列表📕
      • 1094. 拼车
      • 1109. 航班预订统计
      • 2381. 字母移位 II
      • 2406. 将区间分为最少组数
        • 解法1——排序贪心+优先队列
        • 解法2——差分数组
      • 2772. 使数组中的所有元素都等于零
      • 2528. 最大化城市的最小供电站数目(⭐差分数组 + 二分查找答案)
      • 最大化最小化相关题目列表📕
  • Q2:2849. 判断能否在给定时间到达单元格(脑筋急转弯、贪心)
  • Q3:2850. 将石头分散到网格图的最少移动次数⭐⭐⭐(全排列和状态压缩)
    • 解法1——枚举全排列
    • 解法2——最小费用最大流 (TODO)
    • 解法3——状压DP
    • 涉及到「匹配」的题目列表📕
      • 1947. 最大兼容性评分和
        • 解法1——枚举全排列
        • 解法2——状态压缩DP
      • 1349. 参加考试的最大学生数🚹(状态压缩DP)
      • LCP 04. 覆盖🚹(TODO 二分图匹配 & 状态压缩DP)
        • 解法1——二分图匹配
        • 解法2——状态压缩DP
      • 1879. 两个数组最小的异或值之和(状态压缩DP)
      • 2172. 数组的最大与和(状态压缩DP)
  • Q4:2851. 字符串转换⭐
    • 解法1——KMP + 矩阵快速幂优化 DP 🐂
    • 解法2——找规律,无需矩阵快速幂(TODO)
    • [矩阵快速幂] 题目列表📕
  • 成绩记录

竞赛链接

https://leetcode.cn/contest/weekly-contest-362/

Q1:2848. 与车相交的点

https://leetcode.cn/problems/points-that-intersect-with-cars/description/

在这里插入图片描述

提示:
1 <= nums.length <= 100
nums[i].length == 2
1 <= starti <= endi <= 100

解法1——排序后枚举

排序之后按顺序枚举,每次比较和上个区间结束位置之间的关系。

class Solution {public int numberOfPoints(List<List<Integer>> nums) {int ans = 0, last = -1;Collections.sort(nums, (x, y) -> x.get(0) - y.get(0));for (List<Integer> x: nums) {ans += Math.max(0, x.get(1) - Math.max(last + 1, x.get(0)) + 1);last = Math.max(last, x.get(1));}return ans;}
}

解法2——差分数组⭐

https://leetcode.cn/problems/points-that-intersect-with-cars/solutions/2435384/chai-fen-shu-zu-xian-xing-zuo-fa-by-endl-3xpm/

关于差分可见:【算法基础】1.5 前缀和与差分

class Solution {public int numberOfPoints(List<List<Integer>> nums) {int[] diff = new int[102];// 利用差分将区间内所有位置 +1for (List<Integer> p: nums) {diff[p.get(0)]++;diff[p.get(1) + 1]--;}int ans = 0, s = 0;// 检查各个位置  如果>0则ans++for (int d: diff) {s += d;if (s > 0) ans++;}return ans;}
}

差分数组相关题目列表📕

题目列表来源:分享|【算法小课堂】差分数组(Python/Java/C++/Go/JS)

1094. 拼车

https://leetcode.cn/problems/car-pooling/
在这里插入图片描述
提示:

1 <= trips.length <= 1000
trips[i].length == 3
1 <= numPassengersi <= 100
0 <= fromi < toi <= 1000
1 <= capacity <= 10^5

用差分 表示 from 到 to 的范围内增加了多少人,然后再还原。

class Solution {public boolean carPooling(int[][] trips, int capacity) {int[] diff = new int[1002];// 构造差分数组for (int[] t: trips) {diff[t[1]] += t[0];diff[t[2]] -= t[0];}// 差分数组的还原for (int i = 0; i <= 1000; ++i) {if (diff[i] > capacity) return false;diff[i + 1] += diff[i];}return true;}
}

1109. 航班预订统计

https://leetcode.cn/problems/corporate-flight-bookings/

在这里插入图片描述
提示
1 <= n <= 2 * 10^4
1 <= bookings.length <= 2 * 10^4
bookings[i].length == 3
1 <= firsti <= lasti <= n
1 <= seatsi <= 10^4

class Solution {public int[] corpFlightBookings(int[][] bookings, int n) {int[] ans = new int[n], diff = new int[n + 1];for (int[] booking: bookings) {diff[booking[0] - 1] += booking[2];diff[booking[1]] -= booking[2];}for (int i = 0; i < n; ++i) {ans[i] = diff[i];diff[i + 1] += diff[i];}return ans;}
}

2381. 字母移位 II

https://leetcode.cn/problems/shifting-letters-ii/

在这里插入图片描述

提示
1 <= s.length, shifts.length <= 5 * 10^4
shifts[i].length == 3
0 <= starti <= endi < s.length
0 <= directioni <= 1
s 只包含小写英文字母。

class Solution {public String shiftingLetters(String s, int[][] shifts) {int n = s.length();// 构造差分数组int[] diff = new int[n + 1];for (int[] shift: shifts) {int t = shift[2] == 1? 1: -1;diff[shift[0]] += t;diff[shift[1] + 1] -= t;}// 差分数组和答案的还原char[] ans = new char[n];for (int i = 0; i < n; ++i) {ans[i] = op(s.charAt(i), diff[i]);diff[i + 1] += diff[i];}return String.valueOf(ans);}// 对字符 a 移动 xpublic char op(char a, int x) {return (char)(((a - 'a' + x % 26) + 26) % 26 + 'a');}
}

2406. 将区间分为最少组数

https://leetcode.cn/problems/divide-intervals-into-minimum-number-of-groups/
在这里插入图片描述
提示:

1 <= intervals.length <= 1^05
intervals[i].length == 2
1 <= lefti <= righti <= 10^6

解法1——排序贪心+优先队列

按照区间的开始位置从小到大排序。
想象每个组合就是一个列表,我们使用有限队列维护这些列表的末尾位置。
这样每次枚举到一个新的区间,检查是否可以放入已有列表中,如果可以,就将一个已有列表的末尾位置换成当前区间的结尾位置。

class Solution {public int minGroups(int[][] intervals) {Arrays.sort(intervals, (x, y) -> x[0] - y[0]);PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> x - y);for (int[] interval: intervals) {if (!pq.isEmpty() && pq.peek() < interval[0]) pq.poll();pq.offer(interval[1]);}return pq.size();}
}

解法2——差分数组

差分还原中出现的最大值就是答案。

class Solution {public int minGroups(int[][] intervals) {TreeMap<Integer, Integer> diff = new TreeMap<>();int ans = 0, sum = 0;// 计算差分for (int[] interval: intervals) {diff.merge(interval[0], 1, Integer::sum);diff.merge(interval[1] + 1, -1, Integer::sum);}// 还原差分for (Map.Entry<Integer, Integer> entry: diff.entrySet()) {sum += entry.getValue();ans = Math.max(ans, sum);}return ans;}
}

2772. 使数组中的所有元素都等于零

https://leetcode.cn/problems/apply-operations-to-make-all-array-elements-equal-to-zero/

在这里插入图片描述
提示:

1 <= k <= nums.length <= 10^5
0 <= nums[i] <= 10^6

有点差分的思想,又不太一样。

贪心地从前往后枚举每一个位置,只要 > 0 就减,< 0 就返回 false。

class Solution {public boolean checkArray(int[] nums, int k) {int n = nums.length, diff = 0, ans = 0;int[] x = new int[n];for (int i = 0; i < n; ++i) {if (i >= k) diff -= x[i - k];if (nums[i] > diff) {if (n - i < k) return false;ans += nums[i] - diff;      // 更新答案x[i] = nums[i] - diff;      // 记录这个位置减去了多少diff = nums[i];             // 更新diff} else if (nums[i] < diff) return false;}return true;}
}

2528. 最大化城市的最小供电站数目(⭐差分数组 + 二分查找答案)

https://leetcode.cn/problems/maximize-the-minimum-powered-city/
在这里插入图片描述
提示:
n == stations.length
1 <= n <= 10^5
0 <= stations[i] <= 10^5
0 <= r <= n - 1
0 <= k <= 10^9

看到「最大化最小值」或者「最小化最大值」就要想到二分答案,这是一个固定的套路。

class Solution {public long maxPower(int[] stations, int r, int k) {int n = stations.length;long mn = Long.MAX_VALUE;// 计算差分数组long[] cnt = new long[n + 1];for (int i = 0; i < n; ++i) {cnt[Math.max(0, i - r)] += stations[i];cnt[Math.min(n, i + r + 1)] -= stations[i];}// 差分数组的还原for (int i = 0; i < n; ++i) {cnt[i + 1] += cnt[i];mn = Math.min(mn, cnt[i]);}// 二分查找答案long left = mn, right = mn + k;while (left < right) {long mid = left + right + 1 >> 1;if (!check(cnt, mid, r, k)) right = mid - 1;else left = mid;}return left;}// check过程类似 T2772. 使数组中的所有元素都等于零public boolean check(long[] cnt, long x, int r, int k) {long diff = 0;int n = cnt.length - 1;long[] d = new long[n];for (int i = 0; i < n; ++i) {if (i >= 2 * r + 1) diff -= d[i - 2 * r - 1];if (cnt[i] + diff < x) {d[i] = x - cnt[i] - diff;k -= d[i];diff = x - cnt[i];}}return k >= 0;}
}

最大化最小化相关题目列表📕

见:【算法】二分答案 对应部分。

Q2:2849. 判断能否在给定时间到达单元格(脑筋急转弯、贪心)

https://leetcode.cn/problems/determine-if-a-cell-is-reachable-at-a-given-time/

在这里插入图片描述

提示:
1 <= sx, sy, fx, fy <= 109
0 <= t <= 10^9

斜着走,一步顶两步——相当于可以同时横着走和竖着走。 那么只要满足垂直和水平方向中最长的那个距离就好了。

注意有个特例是:只走一步时,如果起点和终点相同就不可以了。

class Solution {public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) {if (sx == fx && sy == fy && t == 1) return false;		// 特例return t >= Math.max(Math.abs(sx - fx), Math.abs(sy - fy));}
}

Q3:2850. 将石头分散到网格图的最少移动次数⭐⭐⭐(全排列和状态压缩)

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/
在这里插入图片描述

提示:

grid.length == grid[i].length == 3
0 <= grid[i][j] <= 9
grid 中元素之和为 9

解法1——枚举全排列

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

将起始点和终点分别放入两个列表,做全排列匹配。
枚举所有全排列,比较各种情况下的移动次数,得出最小移动次数。

class Solution {int ans = Integer.MAX_VALUE, sum = 0;boolean[] st = new boolean[9];public int minimumMoves(int[][] grid) {// 将起始点和终点放入列表List<int[]> src = new ArrayList<>(), dst = new ArrayList<>();for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {while (grid[i][j] > 1) {src.add(new int[]{i, j});grid[i][j]--;}if (grid[i][j] == 0) dst.add(new int[]{i, j});}}// dfs全排列dfs(0, src, dst);return ans;}public void dfs(int i, List<int[]> src, List<int[]> dst) {if (i == src.size()) {ans = Math.min(ans, sum);return;}for (int j = 0; j < dst.size(); ++j) {if (!st[j]) {int[] s = src.get(i), d = dst.get(j);sum += Math.abs(s[0] - d[0]) + Math.abs(s[1] - d[1]);st[j] = true;dfs(i + 1, src, dst);sum -= Math.abs(s[0] - d[0]) + Math.abs(s[1] - d[1]);st[j] = false;}}}
}

解法2——最小费用最大流 (TODO)

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

在这里插入代码片

解法3——状压DP

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435319/zhuang-ya-dp-by-tsreaper-jiw0/

状态压缩DP相比全排列速度更快(48ms vs 3ms)

class Solution {public int minimumMoves(int[][] grid) {// 起始点和目的点放入两个列表List<int[]> L = new ArrayList<>(), R = new ArrayList<>();for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (grid[i][j] == 0) R.add(new int[]{i, j});else {for (; grid[i][j] > 1; grid[i][j]--) {L.add(new int[]{i, j});}}}}// 状态压缩DPint n = L.size();int[] dp = new int[1 << n];Arrays.fill(dp, Integer.MAX_VALUE);dp[0] = 0;for (int i = 1; i < (1<<n); ++i) {// 计算 i 中有几个二进制等于 1——为了确定当前目的点是哪个int cnt = 0;for (int j = 0; j < n; ++j) {cnt += i >> j & 1;}// 状态转移for (int j = 0; j < n; ++j) {   // 枚举所有目标点if ((i >> j & 1) == 1) {    // 检查是否为1,即是否可以从前面转移过来dp[i] = Math.min(dp[i], dp[i ^ (1 << j)] + cost(R.get(cnt - 1), L.get(j)));}}}return dp[(1<<n) - 1];}public int cost(int[] a, int[] b) {return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);}
}

涉及到「匹配」的题目列表📕

题单来源:https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

1947. 最大兼容性评分和

https://leetcode.cn/problems/maximum-compatibility-score-sum/

在这里插入图片描述
提示:
m == students.length == mentors.length
n == students[i].length == mentors[j].length
1 <= m, n <= 8
students[i][k] 为 0 或 1
mentors[j][k] 为 0 或 1

解法1——枚举全排列

数据范围很小,可以枚举出所有学生和老师之间匹配的方案。

class Solution {int ans = 0;boolean[] st = new boolean[8];public int maxCompatibilitySum(int[][] students, int[][] mentors) {// 全排列dfs(students, mentors, 0, 0);return ans;}public void dfs(int[][] students, int[][] mentors, int i, int sum) {if (i == students.length) {ans = Math.max(ans, sum);return;}for (int j = 0; j < mentors.length; ++j) {if (st[j]) continue;st[j] = true;dfs(students, mentors, i + 1, sum + cp(students[i], mentors[j]));st[j] = false;}}// 计算某个学生和某个老师的兼容性评分public int cp(int[] s, int[] t) {int res = 0;for (int i = 0; i < s.length; ++i) {if (s[i] == t[i]) res++;}return res;}
}

解法2——状态压缩DP

class Solution {public int maxCompatibilitySum(int[][] students, int[][] mentors) {int n = students.length;int[][] dp = new int[n + 1][1<<n];  // dp[i][j]表示匹配完i个老师,和集合j的学生的最大匹配和// 枚举每个状态for (int i = 1; i < (1<<n); ++i) {int idx = Integer.bitCount(i);  // 计算该匹配哪个老师了// 枚举每个学生for (int j = 0; j < n; ++j) {if ((i >> j & 1) == 1) {    // 如果可以转移dp[idx][i] = Math.max(dp[idx][i], dp[idx - 1][i ^ (1<<j)] + cp(students[j], mentors[idx - 1]));}}}return dp[n][(1<<n) - 1];}// 计算某个学生和某个老师的兼容性评分public int cp(int[] s, int[] t) {int res = 0;for (int i = 0; i < s.length; ++i) {if (s[i] == t[i]) res++;}return res;}
}

1349. 参加考试的最大学生数🚹(状态压缩DP)

https://leetcode.cn/problems/maximum-students-taking-exam/
在这里插入图片描述

提示:
seats 只包含字符 '.' 和'#'
m == seats.length
n == seats[i].length
1 <= m <= 8
1 <= n <= 8

将每一行选择的位置用一个int变量表示。

枚举每一行,再枚举该行的状态,然后枚举上一行的状态,检测是否合理且可以转移过来。
最后的答案就是最后一行各个状态的最大值。


这里的合理包括:

  1. 该行本身要合理,—— 都要坐在正常的椅子上;同一行的两个学生不能挨边坐。
  2. 每一行和上一行之间不能有冲突——如果上一行的某一列已经坐人了,那么该行该列的左右两侧就不能坐人了。
class Solution {public int maxStudents(char[][] seats) {int m = seats.length, n = seats[0].length;int[] states = new int[m];for (int i = 0; i < m; ++i) {states[i] = getMask(seats[i]);}// 一共m行,每行1<<n种状态int[][] dp = new int[m + 1][1 << n];for (int i = 0; i < 1<<n; ++i) {// 判断 i 是不是 states[0] 的子集 && 自己不冲突if (check(states[0], i) && op(i)) {dp[0][i] = Integer.bitCount(i);}}// 枚举每一行for (int i = 1; i < m; ++i) {// 枚举这一行的每个状态for (int j = 0; j < 1<<n; ++j) {if (!check(states[i], j)) continue;     // 如果这个状态不合理,就跳过// 枚举上一行的每个状态for (int k = 0; k < 1<<n; ++k) {if (!check(states[i - 1], k)) continue; // 如果这个状态不合理,就跳过if (!confilt(k, j)) {               // 如果这个状态和上一行不冲突dp[i][j] = Math.max(dp[i][j], dp[i - 1][k] + Integer.bitCount(j));}}}System.out.println();}return Arrays.stream(dp[m - 1]).max().getAsInt();}// 将一行的状态用一个int表示public int getMask(char[] state) {int res = 0;for (int i = 0; i < state.length; ++i) {if (state[i] == '.') res |= 1 << i;}return res;}// 检查状态x是否是状态state的子集,即是否可选 && 这个状态x本身合法public boolean check(int state, int x) {if ((state | x) != state) return false;      // 需要x是state的子集return op(x);       }// 检查x是否和y作为上一行冲突public boolean confilt(int x, int y) {for (int i = 0; i < 10; ++i) {if ((x >> i & 1) == 1) {    // 如果x这个位置有了// 那么y的相差一列的位置就不能有了if ((y >> i + 1 & 1) == 1 || (y >> i - 1 & 1) == 1) {return true;}}}return false;}// 检查这一行的状态本身是否合理,即检查是否有两个学生坐在挨边的位置上public boolean op(int x) {for (int i = 0; i < 9; ++i) {if ((x >> i & 1) == 1 && (x >> i + 1 & 1) == 1) return false;}return true;}
}

LCP 04. 覆盖🚹(TODO 二分图匹配 & 状态压缩DP)

https://leetcode.cn/problems/broken-board-dominoes/

在这里插入图片描述

限制:
1 <= n <= 8
1 <= m <= 8
0 <= b <= n * m

解法1——二分图匹配

在这里插入代码片

解法2——状态压缩DP

在这里插入代码片

1879. 两个数组最小的异或值之和(状态压缩DP)

https://leetcode.cn/problems/minimum-xor-sum-of-two-arrays/

在这里插入图片描述
提示:
n == nums1.length
n == nums2.length
1 <= n <= 14
0 <= nums1[i], nums2[i] <= 10^7

class Solution {public int minimumXORSum(int[] nums1, int[] nums2) {int n = nums1.length;int[][] dp = new int[n + 1][1 << n];for (int i = 0; i <= n; ++i) Arrays.fill(dp[i], Integer.MAX_VALUE / 2);dp[0][0] = 0;// 枚举nums1的每个状态for (int i = 1; i < 1<<n; ++i) {int cnt = Integer.bitCount(i);// 枚举每个位置for (int j = 0; j < n; ++j) {if ((i >> j & 1) == 1) {dp[cnt][i] = Math.min(dp[cnt][i], dp[cnt - 1][i ^ (1<<j)] + (nums1[j] ^ nums2[cnt - 1]));}}}return dp[n][(1<<n) - 1];}
}

2172. 数组的最大与和(状态压缩DP)

https://leetcode.cn/problems/maximum-and-sum-of-array/
在这里插入图片描述

提示:
n == nums.length
1 <= numSlots <= 9
1 <= n <= 2 * numSlots
1 <= nums[i] <= 15

每个篮子可以放最多 2 个数字,那么可以分成有 2 组一模一样的篮子处理。

注意——要将篮子的使用集合作为状态。

class Solution {public int maximumANDSum(int[] nums, int numSlots) {int n = nums.length, m = 2 * numSlots, ans = 0;int[] dp = new int[1<<m];   // m个篮子的状态// 枚举每个篮子被选择情况for (int i = 1; i < 1<<m; ++i) {// 计算该放入那个num了int cnt = Integer.bitCount(i);if (cnt > n) continue;// 枚举每个被选择的篮子for (int j = 0; j < m; ++j) {if ((i >> j & 1) == 1) {dp[i] = Math.max(dp[i], dp[i ^ (1<<j)] + (nums[cnt - 1] & (j % numSlots + 1)));}}ans = Math.max(ans, dp[i]);}return ans;}
}

Q4:2851. 字符串转换⭐

https://leetcode.cn/problems/string-transformation/
在这里插入图片描述

提示:
2 <= s.length <= 5 * 10^5
1 <= k <= 10^15
s.length == t.length
s 和 t 都只包含小写英文字母。

解法1——KMP + 矩阵快速幂优化 DP 🐂

https://leetcode.cn/problems/string-transformation/solutions/2435348/kmp-ju-zhen-kuai-su-mi-you-hua-dp-by-end-vypf/

计算有多少个 s 的循环同构字符串等于 t,记作 c。这可以用 KMP 等字符串匹配算法解决,即寻找 t 在 s+s(去掉最后一个字符)中的出现次数。(用KMP计算出 s + s 中有几个 t
关于 KMP 可见:我一定要 学会KMP字符串匹配

下面使用动态规划来解决该问题——
定义 f[i][0] 表示 i 次操作后等于 t 的方案数,f[i][1] 表示 i 次操作后不等于 t 的方案数。
在这里插入图片描述
发现 DP 递推式可以写成矩阵乘法形式,因此可以使用矩阵快速幂来优化。(所谓矩阵快速幂,和普通快速幂的思想是一样的。)
在这里插入图片描述
快速幂可以完成从 O ( n ) O(n) O(n) O ( log ⁡ n ) O(\log{n}) O(logn) 的优化。

Q:为什么必须要使用矩阵快速幂?
A:因为 k 的数据范围很大。( log ⁡ n \log{n} logn 对应的数据范围是 1 0 18 10^{18} 1018

class Solution {final long MOD = (long)1e9 + 7;public int numberOfWays(String s, String t, long k) {int n = s.length();// kmp 求出 s+s(去掉最后一个字符) 中有几个 tint c = kmpSearch(s + s.substring(0, n - 1), t);// 递推矩阵long[][] m = {{c - 1, c},{n - c, n - 1 - c},};m = pow(m, k);      // 矩阵快速幂求结果// 根据 s==t? 判断初始状态 对应的答案return s.equals(t)? (int) m[0][0]: (int) m[0][1];}// kmp 返回 s 中有多少个 tpublic int kmpSearch(String s, String t) {int[] next = getNext(s.toCharArray());int c = 0;for (int i = 0, j = -1; i < s.length(); ++i) {while (j != -1 && s.charAt(i) != t.charAt(j + 1)) j = next[j];if (s.charAt(i) == t.charAt(j + 1)) j++;if (j == t.length() - 1) {c++;j = next[j];    // 匹配成功之后,记得要更新 j = next[j]}}return c;}// 求 next 数组public int[] getNext(char[] s) {int n = s.length;int[] next = new int[n];next[0] = -1;for (int i = 1, j = -1; i < n; ++i) {while (j != -1 && s[i] != s[j + 1]) j = next[j];if (s[i] == s[j + 1]) j++;next[i] = j;}return next;}// 矩阵快速幂public long[][] pow(long[][] a, long n) {long[][] res = {{1, 0}, {0, 1}};for (; n > 0; n /= 2) {if (n % 2 == 1) {res = multiply(res, a);}a = multiply(a, a);}return res;}// 矩阵乘法public long[][] multiply(long[][] a, long[][] b) {long[][] c = new long[2][2];for (int i = 0; i < 2; ++i) {for (int j = 0; j < 2; ++j) {c[i][j] = (a[i][0] * b[0][j] + a[i][1] * b[1][j]) % MOD;}}return c;}
}

解法2——找规律,无需矩阵快速幂(TODO)

https://leetcode.cn/problems/string-transformation/solutions/2435714/cjavapython-bu-xu-yao-ju-zhen-kuai-su-mi-cukc/

在这里插入代码片

[矩阵快速幂] 题目列表📕

见:【算法】矩阵快速幂优化动态规划

成绩记录

本次没有参加竞赛。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/80963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP IP网络编程(五) 基于TCP的服务器端、客户端 (补充)

文章目录 回声客户端的完美实现回声客户端出现的问题回声客户端问题解决方法 TCP原理TCP套接字中的I/O缓冲TCP内部工作原理1&#xff1a;与对方套接字的连接TCP内部工作原理2&#xff1a;与对方主机的数据交换TCP内部工作原理3&#xff1a;断开与套接字的连接 回声客户端的完美…

双向链表的实现(增删查改)——最好理解的链表

双向链表的实现 一&#xff0c;双向链表的特点二&#xff0c;双向链表的结构三&#xff0c;双向链表的内容实现3.1创建node节点3.2初始化3.3打印3.4插入3.4.1尾插3.4.2头插3.4.3在pos位置上插入 3.5删除3.5.1尾删3.5.2头删3.5.3删除pos位置上的数据 四&#xff0c;调试技巧&…

day21算法

常见的七种查找算法&#xff1a; ​ 数据结构是数据存储的方式&#xff0c;算法是数据计算的方式。所以在开发中&#xff0c;算法和数据结构息息相关。今天的讲义中会涉及部分数据结构的专业名词&#xff0c;如果各位铁粉有疑惑&#xff0c;可以先看一下哥们后面录制的数据结构…

【C++学习】继承

目录 一、继承的概念及定义 1、继承的概念 2、继承的定义 2.1 定义格式 2.2 继承关系和访问限定符 2.3 继承基类成员访问方式的变化 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员 七、复杂的菱形…

SpringMvc第五战-【SpringMvcJSR303和拦截器】

前言&#xff1a; 小编阐述了springmvc 中的文件下载&#xff0c;以及jrebel的使用和文件下载以及多文件下载! 在本次小编将会介绍JSR303的概念&#xff0c;应用场景和在具体实例的使用&#xff1b;和拦截器的应用 一.JSR303的介绍 1.什么是JSR303&#xff1f; JSR是Java S…

Aztec的隐私抽象:在尊重EVM合约开发习惯的情况下实现智能合约隐私

1. 引言 Aztec的架构&#xff0c;不同于当前“通过EVM兼容执行环境”所实现的区块链水平扩容趋势。Aztec内部笑称其构建的为首个非zkEVM协议。 Aztec专注于实现&#xff1a; 成为理解和需要智能合约隐私的开发者的终极解决方案。 Aztec为开发者提供构建隐私优先app所需的网…

【微信小程序开发】宠物预约医疗项目实战-环境配置与Vant UI集成

第一章 宠物预约医疗项目实战-环境配置与Vant UI集成 文章目录 前言一、Vant UI是什么&#xff1f;二、使用步骤2.1 安装 node.js2.2 通过 npm 安装vant2.3 修改 app.json2.4 修改 project.config.json2.5 构建 npm 包2.6 使用组件全局引入和局部引入全局引入局部引入 前言 Va…

基于Java+SpringBoot+Vue+uniapp点餐小程序(亮点:协同过滤算法、会员系统,购物车结算、在线聊天)

校园点餐小程序 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序&#xff08;小蔡coding&#xff09;2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 系统功能结构设计4.2 主要功能描述 五…

SpringBoot整合Flowable

1. 配置 &#xff08;1&#xff09; 引入maven依赖 <dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.7.2</version></dependency><!-- MySQL连接 -->&l…

MySQL--MySQL索引事务

事务的概念 事务指逻辑上的一组操作&#xff0c;组成这组操作的各个单元&#xff0c;要么全部成功&#xff0c;要么全部失败。 在不同的环境中&#xff0c;都可以有事务。对应在数据库中&#xff0c;就是数据库事务。 使用 &#xff08;1&#xff09;开启事务&#xff1a;start…

什么是接口自动化?为什么要做?和怎么做接口自动化?

服务端接口测试介绍 什么是服务端&#xff1f; 一般所说的服务端是指为用户在 APP 或 PC 使用的互联网功能提供数据服务的背后的一切。以天猫精灵智能音箱系列的产品链路为例&#xff0c;服务端便是网关&#xff08;包括网关在内&#xff09;之后的链路。 什么是接口&#xf…

【自然语言处理】【大模型】RWKV:基于RNN的LLM

相关博客 【自然语言处理】【大模型】RWKV&#xff1a;基于RNN的LLM 【自然语言处理】【大模型】CodeGen&#xff1a;一个用于多轮程序合成的代码大语言模型 【自然语言处理】【大模型】CodeGeeX&#xff1a;用于代码生成的多语言预训练模型 【自然语言处理】【大模型】LaMDA&a…

深入网络底层,了解Linux系统收发网络数据包的过程、原理、流程,附图文说明

深入网络底层&#xff0c;了解Linux系统收发网络数据包的过程、原理、流程&#xff0c;附图文说明。 Linux 服务器收到网络数据包&#xff0c;需要经过哪些处理&#xff0c;一步步将数据传给应用进程的呢&#xff1f;应用进程发送数据包时&#xff0c;Linux 又是如何操作将数据…

android studio platform使用体验分享(as无法跳转c/c++等native源码的福音,强烈推荐)

hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01;这些天粉丝朋友们分享了一下Android Studio for Platform 这个最新的google开发的阅读aosp源码的工具&#xff0c;特别适合做原生系统开发。具体官方介绍如下地址&#xff1a; 参考链接&#xff1a;https://developer.…

react的状态管理简单钩子方法

1.recoil useProvider文件: import { atom, useRecoilState } from recoil;const initState atom({key: initState,default: {state: [],}, })// 将业务逻辑拆分到一个单独文件中&#xff0c;方便进行状态管理 export interface StateProps {id: number;text: string;isFini…

异地远程访问本地SQL Server数据库【无公网IP内网穿透】

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 Cpolar下载安装3.2 Cpolar的注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 现在我们身边的只能设备越来越多&#xff…

文心一言 VS 讯飞星火 VS chatgpt (94)-- 算法导论9.2 3题

三、用go语言&#xff0c;给出 RANDOMIZED-SELECT的一个基于循环的版本。 文心一言&#xff1a; 在循环中实现 RANDOMIZED-SELECT 的一个版本可以如下所示。这个版本使用 Go 语言编写&#xff0c;利用随机化来选择一个元素&#xff0c;并在循环中不断地调整选择的元素&#x…

【探索Linux】—— 强大的命令行工具 P.8(进程地址空间)

阅读导航 前言一、内存空间分布二、什么是进程地址空间1. 概念2. 进程地址空间的组成 三、进程地址空间的设计原理1. 基本原理2. 虚拟地址空间 概念 大小和范围 作用 虚拟地址空间的优点 3. 页表 四、为什么要有地址空间五、总结温馨提示 前言 前面我们讲了C语言的基础知识&am…

HTTP协议(超级详细)

HTTP协议介绍 基本介绍&#xff1a; HTTP&#xff1a;超文本传输协议&#xff0c;是从万维网服务器传输超文本到本地浏览器的传送协议HTTP是一种应用层协议&#xff0c;是基于TCP/IP通信协议来传送数据的&#xff0c;其中 HTTP1.0、HTTP1.1、HTTP2.0 均为 TCP 实现&#xff0…

vue组件库开发,webpack打包,发布npm

做一个像elment-ui一样的vue组件库 那多好啊&#xff01;这是我前几年就想做的 但webpack真的太难用&#xff0c;也许是我功力不够 今天看到一个视频&#xff0c;早上6-13点&#xff0c;终于实现了&#xff0c;呜呜 感谢视频的分享-来龙去脉-大家可以看这个视频&#xff1a;htt…