【一】LZ信息营-算法课程体系与题目库清单

📊 课程体系总览表

课程编号课程主题核心算法/数据结构难度等级关联考核模块关键考点
01理解递归函数递归、DFS、汉诺塔★★☆☆☆搜索基础递归思维、分治思想
02时间复杂度与排序排序算法、复杂度分析☆☆☆☆算法基础复杂度分析、排序优化
03STL库的应用vector、map、priority_queue★★☆☆☆数据结构基础STL熟练度、容器选择
04网格寻路与BFSBFS、队列、路径搜索★★★☆☆图论搜索BFS模板、状态表示
05图论与最短路算法Dijkstra、负环、差分约束★★★★图论基础最短路建模、算法选择
06听说大家喜欢数学题矩阵快速幂、逆元、扩展欧几里得★★★★数学基础数论公式、快速幂
07神奇的树状数组BIT、差分、逆序对★★★☆☆高级数据结构区间查询、单点更新
08听说大家都学过贪心排序贪心、后悔贪心★★★☆☆贪心策略贪心选择、证明
09二分枚举与按位枚举二分答案、按位枚举★★★☆☆高效枚举二分模板、状态压缩
10背包九讲01背包、完全背包、多重背包★★★★动态规划背包模型、状态优化
11暴力枚举的艺术回溯、DFS剪枝、双向搜索★★★☆☆枚举优化剪枝技巧、状态压缩
12经典动态规划问题线性DP、环形DP、股票问题★★★★动态规划状态设计、转移方程
13区间统计问题研究线段树、单调队列、离散化★★★★区间算法区间查询、离线处理
14筛法只能求质数?欧拉筛、约数个数、欧拉函数★★★★数论算法筛法优化、积性函数
15数论分块整除分块、下取整求和★★★★★数学优化分块思想、公式推导
16贡献思维和单调栈单调栈、贡献法★★★★单调结构贡献计算、单调栈模板
17如何设计你的状态状态DP、状态压缩★★★★动态规划状态设计、压缩技巧
18尺取法和双指针滑动窗口、同向双指针★★★☆☆双指针窗口维护、指针移动
19神奇的根号算法数论分块、莫队算法★★★★★分块算法根号分治、复杂度平衡
20前缀和优化技巧前缀和、哈希表、差分★★★☆☆前缀优化区间和转换、哈希优化
21生成树与并查集Kruskal、并查集、最小生成树★★★★图论算法连通性判断、贪心选择

📝 各课程题目库详细整理

【课程01】理解递归函数

核心概念:递归三要素、记忆化递归、分治思想

题目编号题目名称算法类型关键解法难度
LS1209斐波那契数列递归/记忆化递归+记忆化,避免重复计算☆☆☆☆
NC22227约瑟夫环递归公式f(n,m)=(f(n1,m)+m)★★☆☆☆
LS1012约瑟夫环2递归/迭代数学公式推导★★☆☆☆
LS1028汉诺塔问题递归分治move(n,A,B,C) = move(n-1,A,C,B) + move(1,A,B,C) + move(n-1,C,B,A)★★☆☆☆
LS1117滑雪记忆化搜索DFS+记忆化,dp[i][j]=max(四个方向)★★★☆☆
LS108201背包递归/记忆化dfs(i,c)=max(dfs(i1,c),dfs(i1,cw[i])+v[i])★★★☆☆
LS1023计算乘方快速幂递归pow(a,b) = b%2==0? pow(aa,b/2) : a*pow(a,b-1)★★☆☆☆
LS1025最大公约数递归辗转相除gcd(a,b)=gcd(b,a%b)☆☆☆☆
LS1083完全背包递归/记忆化dfs(i,c)=max(dfs(i-1,c), dfs(i,c-w[i])+v[i])★★★☆☆
LS1024计算乘方和递归分治sum_pow(a,b)=b%2==0? (1+pow(a,b/2))*sum_pow(a,b/2-1): pow(a,b)+sum_pow(a,b-1)★★★☆☆

【课程02】时间复杂度与排序

核心概念:复杂度分析、排序算法比较、自定义排序

题目编号题目名称算法类型关键解法难度
LS1030比较排序算法排序复杂度分析不同排序算法时间复杂度☆☆☆☆
LS1212自定义排序排序规则自定义cmp函数,lambda表达式★★☆☆☆
LS1031排序后输出位置稳定排序记录原始位置,按值排序后输出索引★★☆☆☆
LS1032求两数之和的最大值排序贪心排序后两端取数,复杂度分析★★☆☆☆

【课程03】STL库的应用

核心概念:STL容器选择、算法函数使用、性能分析

题目编号题目名称数据结构关键解法难度
LS1033坐标排序vector+sort自定义排序规则☆☆☆☆
LS1034去重后第k小整数set/排序set自动去重排序,或sort+unique★★☆☆☆
LT3556质数字符串string操作字符串查找、质数判断★★☆☆☆
LS1038二维vector嵌套容器vector<vector>操作★★☆☆☆
LS1039多个priority_queue优先队列大顶堆、小顶堆应用★★☆☆☆
LS1035上网统计map统计map<string, int>计数★★☆☆☆
LS1037有序表的最小和多路归并priority_queue维护k路最小元素★★★☆☆
LS1040数据流中的众数map统计实时更新频率,维护当前众数★★★☆☆
LS1036出题法则复杂排序多关键字排序,自定义比较★★★☆☆
LS1041数据流中的中位数双堆维护大顶堆存较小一半,小顶堆存较大一半★★★★

【课程04】网格寻路与BFS

核心概念:BFS模板、状态表示、路径记录

题目编号题目名称算法类型关键解法难度
B3616【模板】队列队列基础STL queue基本操作☆☆☆☆
B3625能否通过迷宫BFS基础BFS判断连通性★★☆☆☆
P1443马的遍历BFS最短路8方向BFS,记录步数★★☆☆☆
P1135奇怪的电梯BFS状态状态=(楼层),BFS求最少按键次数★★☆☆☆
P1451细胞BFS连通块统计连通块数量★★☆☆☆
P1162填涂颜色BFS染色从边界BFS,区分内外★★★☆☆
LS1216迷宫寻路BFS+状态状态=(位置),BFS求最短路径★★★☆☆
P1649最少拐弯次数BFS方向状态=(位置,方向),记录拐弯次数★★★☆☆
LS1217推箱子1BFS+状态状态=(人位置,箱子位置),双重BFS★★★★
LS1218推箱子2BFS+复杂状态状态压缩,多个箱子★★★★
P1825传送迷宫BFS+传送门传送门特殊处理,记录传送状态★★★★
D0326混水摸鱼BFS+多目标多源BFS,计算最短距离★★★☆☆
B3656【模板】双端队列数据结构deque基本操作★★☆☆☆
P4554小明的游戏BFS+不同代价0-1 BFS或Dijkstra★★★☆☆

【课程05】图论与最短路算法

核心概念:Dijkstra、负环检测、差分约束

题目编号题目名称算法类型关键解法难度
LS1219如何封装我的算法代码封装函数封装,提高复用性★★☆☆☆
LS1039多个priority_queue堆优化Dijkstra的堆优化实现★★☆☆☆
P4779【模板】单源最短路径Dijkstra堆优化Dijkstra模板★★★☆☆
P3385【模板】负环SPFA/BellmanSPFA判负环,入队次数>n★★★★
P4568飞行路线分层图Dijkstra状态=(节点,使用次数),建k+1层图★★★★
LS1095旅游巴士最短路+时间限制Dijkstra+时间窗口★★★★
P5960【模板】差分约束SPFA/不等式将不等式转化为边,求最长路/最短路★★★★
P1629邮递员送信往返最短路正向+反向图,两次Dijkstra★★★☆☆
LS1108聚会多源最短路从多个点出发的最短路★★★☆☆

【课程06】听说大家喜欢数学题

核心概念:矩阵快速幂、逆元、扩展欧几里得

题目编号题目名称算法类型关键解法难度
LS1156斐波那契数列_矩阵加速矩阵快速幂[[1,1],[1,0]]^n★★★★
LS1161斐波那契数列_更复杂矩阵扩展更高阶递推的矩阵表示★★★★
LS1220扩展欧几里得算法扩展欧几里得ax+by=gcd(a,b)求解★★★★
LS1024计算乘方和快速幂+等比求和分治求等比数列和★★★☆☆

【课程07】神奇的树状数组

核心概念:BIT单点更新区间查询、差分、逆序对

题目编号题目名称算法类型关键解法难度
LS0010【课件】神奇的树状数组BIT模板树状数组基本原理和操作★★☆☆☆
P3374【模板】单点更新,区间求和BIT基础add(x,v), sum(r)-sum(l-1)★★☆☆☆
LS1104差分与前缀和差分数组区间更新,单点查询★★★☆☆
P3368【模板】区间更新,单点求和BIT+差分维护差分数组,单点查询即前缀和★★★☆☆
P3372【模板】区间更新,区间求和BIT+差分扩展维护两个BIT:B1[i], B2[i]★★★★
P1908逆序对BIT+离散化从右向左扫描,统计比当前小的个数★★★☆☆

【课程08】听说大家都学过贪心

核心概念:线段覆盖、排序贪心、后悔贪心

题目编号题目名称算法类型关键解法难度
LS1058看电影线段覆盖按结束时间排序,贪心选择★★☆☆☆
LS1060线段覆盖区间选择按右端点排序,不相交则选择★★★☆☆
LS1061排队难题排序贪心调整顺序使总等待时间最小★★★☆☆
LS1062拼接字符串字典序贪心自定义排序:a+b<b+a则a在前★★★☆☆
LS1197后悔贪心反悔贪心优先队列维护可选集合★★★★
LS1064逛超市_简单贪心选择按性价比排序选择★★★☆☆
LS1065逛超市_困难后悔贪心先买再后悔替换★★★★
LS1059剪刀石头布策略贪心根据对手历史选择最优策略★★★☆☆
LS1066最小差值排序贪心排序后取相邻差最小值★★☆☆☆
LS1063添加最少硬币贪心构造确保1~x都能表示,添加x+1★★★☆☆

【课程09】二分枚举与按位枚举

核心概念:二分答案、按位枚举、最大化最小值

题目编号题目名称算法类型关键解法难度
LS1072分割数组的最大值二分答案最小化最大值,贪心检查可行性★★★☆☆
LS1074分割数组的最小值二分答案最大化最小值,贪心检查★★★☆☆
LS1073查找元素位置二分查找lower_bound, upper_bound★★☆☆☆
LS1079导弹拦截贪心+二分最长不升子序列,O(nlogn)★★★★
LS1075青蛙过河二分答案+贪心检查能否跳过,维护可达位置★★★★
P13822白露为霜二分查找在有序数组中查找特定条件★★★☆☆
LS1077数的三次方根浮点数二分二分求立方根,控制精度★★☆☆☆
LS1078最大化平均值二分答案+转化分数规划,检查∑(ai-x*bi)≥0★★★★
P12733磨合二分答案最小化最大值问题★★★☆☆
P4377Talent Show G二分答案+背包分数规划,0-1分数背包★★★★

【课程10】背包九讲

核心概念:01背包、完全背包、多重背包、分组背包

题目编号题目名称背包类型关键解法难度
LS0008【课件】背包九讲综合模板各类背包问题模板★★★☆☆
LS108201背包01背包dp[j] = max(dp[j],dp[j-w]+v)逆序★★☆☆☆
LS123201背包之201背包变体容量恰好为C的最大价值★★★☆☆
LS1083完全背包完全背包dp[j] = max(dp[j],dp[j-w]+v)顺序★★☆☆☆
LS1084多重背包多重背包二进制拆分优化★★★☆☆
LS1085混合背包混合背包分类处理,01逆序,完全顺序★★★★
LS1086二维费用背包二维背包dp[j][k]双重循环★★★☆☆
LS1087分组背包分组背包每组最多选一个,组内循环★★★★
LS1088有依赖的背包树形背包树形DP,后序遍历★★★★★
LS1093求背包的具体方案方案输出记录转移路径,逆向推导★★★★
LS1229受限的数据背包优化根据数据范围选择算法★★★★

【课程11】暴力枚举的艺术

核心概念:回溯、剪枝、状态压缩、双向搜索

题目编号题目名称算法类型关键解法难度
LS1133部分和问题DFS回溯每个数选或不选★★☆☆☆
LS1129排列数字全排列DFS回溯,vis标记★★☆☆☆
LS1130组合数字组合枚举DFS回溯,限制长度★★☆☆☆
LS1131八皇后DFS回溯行、列、对角线检查★★★☆☆
P1123取数游戏DFS+剪枝不能相邻取数,最大和★★★☆☆
P4799世界冰球锦标赛折半搜索分成两半,分别枚举再合并★★★★
LS1128铺地砖状态压缩DP状压DP,转移考虑铺砖方式★★★★
LS1193激光枪枚举+几何枚举直线,统计线上点数★★★★
P3067平衡子数组折半枚举分成两半,meet in the middle★★★★★

【课程12】经典动态规划问题

核心概念:线性DP、环形处理、股票问题系列

题目编号题目名称算法类型关键解法难度
LS1016最大子数组和线性DPKadane算法,dp[i] = max(nums[i],dp[i-1]+nums[i])★★☆☆☆
LS1250最大子数组和线性DP同上,基础模板题★★☆☆☆
LS1181最大2段和分段DP前后缀分解,pre[i] + suf[i+1]★★★☆☆
LS1251最大环形子数组和环形DP两种情况:不环形(正常),环形(总和-最小子数组和)★★★★
LS1176买卖股票的最佳时机_1一次交易记录历史最小值,计算最大差价★★☆☆☆
LS1177买卖股票的最佳时机_2无限交易贪心:所有上涨都交易★★☆☆☆
LS1178买卖股票的最佳时机_3最多两次前后缀分解,前后各一次最大★★★★
LS1252买卖股票的最佳时机_4最多k次dp[i][j][0/1] 第i天第j次交易持有/不持有★★★★★
LS1179买卖股票含冷冻期状态机DP三个状态:持有、不持有(冷冻)、不持有(非冷冻)★★★★
LS1253买卖股票的最佳时机_5含手续费状态机DP,卖出时扣除手续费★★★★
P1121环状最大两段子段和环形分段最大两段和,考虑环形情况★★★★★

【课程13】区间统计问题研究

核心概念:线段树、单调队列、离散化、逆序对

题目编号题目名称数据结构关键解法难度
LS1226平缓的曲线线段树区间最大值最小值查询★★★☆☆
P3374【模板】单点更新,区间求和线段树/BIT基础线段树模板,维护区间和★★☆☆☆
P1908逆序对BIT/线段树离散化+从右向左统计★★★☆☆
LS1227单点更新,区间最值线段树维护区间最大值★★★☆☆
LS1228构造回文数组线段树/贪心对称位置配对,区间查询辅助★★★★
P1886滑动窗口单调队列维护窗口最大值/最小值★★★☆☆
P1725琪露诺单调队列优化DPdp[i] = max(dp[i-k..i-1])+a[i],单调队列维护★★★★
P2344Generic Cow Protests树状数组优化DPdp[i]=∑dp[j] where sum[j+1..i]≥0★★★★

【课程14】筛法只能求质数?

核心概念:欧拉筛、约数个数、约数和、欧拉函数

题目编号题目名称算法类型关键解法难度
LS1163埃氏筛和欧拉筛筛法基础埃氏筛O(nloglogn),欧拉筛O(n)★★☆☆☆
LS1233多个数分解质因数质因数分解预处理最小质因子,快速分解★★★☆☆
LS1234相等约数相关使用约数个数/约数和公式★★★☆☆
LS1236区间筛法区间筛[L,R]区间筛,用质数筛区间★★★★
LS1231连续的自然数筛法应用欧拉筛求连续质数/合数★★★★
LS1235最值求高约数问题最大公约数相关性质★★★☆☆
LS1237最大公约数计数GCD计数使用欧拉函数性质★★★★
LS1164约数个数、约数和、欧拉函数筛法求积性函数线性筛同时计算d(n),σ(n),φ(n)★★★★

【课程15】数论分块

核心概念:整除分块、下取整求和、公式推导

题目编号题目名称算法类型关键解法难度
P2398GCD SUM数论分块∑∑gcd(i,j) = ∑φ(d)*floor(n/d)²★★★★★
LS1230简洁的数学数论分块∑floor(n/i)*i 优化计算★★★★
P2261余数求和数论分块∑k%i = nk - ∑floor(k/i)i★★★★
LS1261【提高】数论分块基础分块计算∑floor(n/i)★★★☆☆
LS1262【提高】多维数论分块多维分块∑∑floor(n/i)*floor(m/j)★★★★

【课程16】贡献思维和单调栈

核心概念:单调栈、贡献法、子数组统计

题目编号题目名称算法类型关键解法难度
LS1247接雨水单调栈每个位置能接的水 = min(左边最大,右边最大) - 高度★★★☆☆
LS1243子数组之和贡献法统计每个元素在多少子数组中★★☆☆☆
LS1244子数组的最小值之和单调栈找到每个元素作为最小值的左右边界★★★★
LS1199柱状图中最大的矩形单调栈找到每个柱子左右第一个更矮的★★★★
LS1200最大矩形单调栈+逐行处理每行作为底,转化为柱状图问题★★★★
LS1245子数组的最值之差单调栈分别统计最大值贡献和最小值贡献★★★★
LS1246子序列的最值之差贡献法考虑每个元素作为最大/最小的贡献★★★★
LS1248二进制中的个数位运算+贡献统计每个bit位在多少子数组中为1★★★★
LS1249异或和异或+贡献按位考虑,统计异或贡献★★★★

【课程17】如何设计你的状态

核心概念:状态设计、状态压缩、多维DP

题目编号题目名称算法类型关键解法难度
LS1016最大子数组和状态DPdp[i]表示以i结尾的最大子数组和★★☆☆☆
LS1250最大子数组和状态优化滚动变量替代数组★★☆☆☆
LS1181最大2段和状态分解pre[i]前i个的最大一段,suf[i]后i个的最大一段★★★☆☆
LS1251最大环形子数组和状态分类分两种情况:不跨环和跨环★★★★
LS1176买卖股票1状态机两个状态:持有股票、不持有股票★★☆☆☆
LS1177买卖股票2状态机贪心简化,所有上涨都交易★★☆☆☆
LS1178买卖股票3状态机四个状态:第一次持有/不持有,第二次持有/不持有★★★★
LS1252买卖股票4状态机2k个状态,奇数次持有,偶数次不持有★★★★★
LS1179买卖股票含冷冻期状态机三个状态:持有、冷冻期、可购买★★★★
LS1253买卖股票5状态机含手续费,卖出时扣除★★★★

【课程18】尺取法和双指针

核心概念:滑动窗口、同向双指针、相向双指针

题目编号题目名称算法类型关键解法难度
LS12562数之和相向双指针排序后左右指针向中间移动★★☆☆☆
LS12572数之差相向双指针排序后固定差值找目标★★★☆☆
LS1255k个最接近的数双指针+滑动窗口找到最近位置后扩展窗口★★★☆☆
P1638包含所有数的最短区间滑动窗口统计窗口内不同元素个数★★★☆☆
LS1259字符出现至少k次的子字符串滑动窗口统计字符频率,满足条件时收缩★★★★
LS1260求和游戏前缀和+双指针维护窗口和,寻找目标区间★★★★
LS1254统计稳定子数组的数目双指针维护最大最小值,统计稳定区间★★★★
LS1258极差不超过k的分割数双指针+滑动窗口维护窗口极差,统计分割方式★★★★
B4196赛车游戏双指针应用根据速度差计算超车次数★★★☆☆

【课程19】神奇的根号算法

核心概念:根号分治、莫队算法、分块思想

题目编号题目名称算法类型关键解法难度
LS1261【提高】数论分块数论分块∑floor(n/i)分块计算★★★☆☆
LS1262【提高】多维数论分块多维分块∑∑floor(n/i)*floor(m/j)★★★★
P2261余数求和数论分块nk - ∑floor(k/i)i★★★★
P3901数列找不同莫队算法离线查询区间是否有重复★★★★
P1494小Z的袜子莫队算法概率计算,组合数公式★★★★★
P2709小B的询问莫队算法维护平方和,∑cnt[i]²★★★★
LS1263【省选】智力与模数根号分治根据模数大小分情况处理★★★★★

【课程20】前缀和优化技巧

核心概念:前缀和、哈希表、差分数组

题目编号题目名称算法类型关键解法难度
LS1265连续数组前缀和+哈希0视为-1,求最长和为0子数组★★★☆☆
LS1264异或子数组前缀异或+哈希异或前缀和,a ⊕ b = 0 等价于 a = b★★★★
LS1267最长的平衡子串1前缀和+状态统计 0 和 1 的个数差★★★☆☆
LS1266最长的平衡子串2前缀和扩展多种字符的平衡条件★★★★
LS1269维护数组前缀和+差分区间更新,前缀查询★★★☆☆
P14253旅行前缀和优化预处理前缀信息,快速计算★★★★
P14359异或和前缀异或按位统计,前缀异或性质★★★★
LS1270Load_Balancing_S前缀和分割枚举分割点,前缀后缀统计★★★★
LS1268【提高】异或序列前缀异或区间异或 = prefix[r] ⊕ prefix[l-1]★★★★

【课程21】生成树与并查集

核心概念:Kruskal、并查集、最小生成树

题目编号题目名称算法类型关键解法难度
P1551亲戚并查集基础连通性判断,union-find★★☆☆☆
LS1276【算法】最小生成树Kruskal按边权排序,贪心选择★★★☆☆
LS1272【算法】最小比率生成树分数规划二分答案,转化为最小生成树★★★★★
P1194买礼物最小生成树变体建图技巧,虚拟节点★★★★
P2700逐个击破并查集+贪心逆向思维,从大到小合并★★★★★
P1396营救最小生成树最大边权最小,Kruskal★★★☆☆
LS1275【算法】删边游戏并查集+离线离线处理,反向加边★★★★★
LS1273【算法】撤销与合并可持久化并查集主席树维护并查集历史★★★★★
LS1274【算法】向右看齐并查集应用维护下一个可用位置★★★★

🎯 考核重点与备考策略

基础必考模块(60分)

  1. 递归与搜索(课程01、04):DFS/BFS模板

  2. 排序与STL(课程02、03):sort、容器使用

  3. 基础DP(课程12、17):线性DP、状态设计

  4. 贪心与双指针(课程08、18):经典贪心、滑动窗口

  5. 数据结构基础(课程07):树状数组基本操作

核心提高模块(30分)

  1. 动态规划进阶(课程10):背包九讲

  2. 图论算法(课程05):最短路、生成树

  3. 高级数据结构(课程13):线段树、单调队列

  4. 数学基础(课程06、14):快速幂、筛法

高级挑战模块(10分)

  1. 数论与分块(课程15、19):数论分块、根号算法

  2. 贡献思维(课程16):单调栈、贡献法

  3. 前缀优化(课程20):前缀和技巧


📚 备考建议

第一阶段:基础巩固(1-2周)

第二阶段:核心提升(2-3周)

第三阶段:高级突破(1-2周)

第四阶段:模拟冲刺(1周)


✅ 快速查找表(按算法类型)

算法类型推荐课程关键题目掌握要点
递归/DFS01LS1028汉诺塔,LS1117滑雪递归边界、记忆化
BFS搜索04P1443马的遍历,P1825传送迷宫状态表示、队列使用
动态规划10,12,17LS1082 01背包,LS1176股票问题状态设计、转移方程
贪心算法08LS1058看电影,LS1060线段覆盖贪心策略证明
双指针18LS1256两数之和,P1638最短区间滑动窗口维护
数据结构03,07,13P3374线段树,P1908逆序对区间操作、离散化
图论05,21P4779最短路,LS1276最小生成树Dijkstra、Kruskal
数学/数论06,14,15LS1156矩阵快速幂,P2261余数求和快速幂、筛法、分块
高级技巧16,19,20LS1199最大矩形,P1494小Z的袜子单调栈、莫队、前缀和

最后提醒:信息营选拔考察综合能力,不仅要掌握算法,还要能灵活运用。建议按照课程顺序循序渐进,打好基础后再挑战难题。每道题目都要理解透彻,做到举一反三。

预祝各位同学在信息营选拔中取得优异成绩! 🚀

 

 




【二】LZ信息营-选拔考核全方位复习指南

📚 完整课程体系与算法分类

算法分类体系


🚀 核心算法模板库(使用i64)

一、递归与搜索模块

1.1 归三要素模板

📊 递归三要素总结

要素说明示例(阶乘)
定义明确函数的功能和参数factorial(n) 计算n的阶乘
边界最小情况,递归出口n <= 1 时返回1
递推如何分解为子问题factorial(n) = n × factorial(n-1)

📊 常见递归问题分类

问题类型特点经典例题
数学计算直接数学公式递归阶乘、斐波那契、组合数
分治算法分而治之,合并结果归并排序、快速排序
回溯算法尝试所有可能,回溯全排列、组合、N皇后
树形递归处理树状结构二叉树遍历、树的高度
图遍历图的深度优先搜索迷宫问题、连通分量
动态规划重叠子问题,记忆化斐波那契(记忆化)

📊 递归复杂度分析

递归类型时间复杂度空间复杂度示例
线性递归O(n)O(n)阶乘、链表遍历
二叉树递归O(n)O(h)二叉树遍历
指数递归O(2^n)O(n)朴素斐波那契
分治递归O(nlogn)O(logn)归并排序
组合递归O(C(n,k))O(k)组合问题
排列递归O(n!)O(n)全排列

📊 递归优化技术

优化技术原理应用场景
记忆化缓存计算结果,避免重复计算斐波那契、动态规划
尾递归递归调用在最后,可优化为迭代某些累加、累乘
迭代转换使用栈模拟递归深度过大时避免栈溢出
剪枝提前终止不可能的分支回溯算法、搜索
分治优化减少子问题规模快速排序、归并排序

📊 递归 vs 迭代对比

方面递归迭代
代码简洁性高,更接近数学定义低,需要显式控制
可读性高,逻辑清晰低,需要理解循环
空间效率低,有栈开销高,只有变量
性能可能有函数调用开销通常更快
栈溢出风险有,深度过大时无,只有堆内存限制
适用场景树、图、分治问题线性处理、简单循环

📊 递归常见错误与规避

错误类型现象规避方法
无边界条件无限递归,栈溢出总是先写边界条件
边界条件错误提前终止或漏解仔细测试边界情况
重复计算指数级复杂度使用记忆化缓存结果
栈溢出递归深度过大改为迭代或尾递归优化
逻辑错误递推关系错误验证小规模情况
状态污染全局变量影响使用参数传递状态

📊 关联题目索引

题目编号题目名称核心递归难度
LS1023计算乘方快速幂递归⭐⭐
LS1028汉诺塔问题经典递归⭐⭐
LS1209斐波那契数列记忆化递归⭐⭐
NC22227约瑟夫环数学递归⭐⭐⭐
LS1054全排列问题回溯递归⭐⭐⭐
LS1065组合问题组合递归⭐⭐⭐

【递归核心要点】

方面关键点示例
三要素定义、边界、递推factorial(n) = n × factorial(n-1)
设计步骤分析问题,确定递归结构汉诺塔:移动n-1个,移动第n个,移动n-1个
优化技术记忆化、尾递归、迭代转换斐波那契记忆化避免重复计算
复杂度分析递归树,主定理归并排序:T(n) = 2T(n/2) + O(n)

【学习建议】

  1. 理解原理:掌握递归的数学基础(数学归纳法)

  2. 从简单开始:先实现阶乘、斐波那契等简单递归

  3. 画递归树:帮助理解递归过程和复杂度

  4. 掌握优化:学习记忆化、迭代转换等优化技术

  5. 多实践:解决各种递归问题,积累经验

【常见错误】

  1. 无限递归:忘记边界条件或边界条件错误

  2. 栈溢出:递归深度过大,改为迭代

  3. 重复计算:未使用记忆化,指数级复杂度

  4. 逻辑错误:递推关系不正确

  5. 状态污染:错误使用全局变量

【性能优化】

  1. 记忆化:缓存计算结果

  2. 尾递归优化:某些编译器可优化

  3. 迭代转换:使用栈模拟递归

  4. 动态规划:自底向上计算

  5. 剪枝:提前终止不可能的分支

【调试技巧】

  1. 打印递归深度:cout << "递归深度: " << depth << endl;

  2. 小数据测试:验证边界情况和简单情况

  3. 画递归树:可视化递归过程

  4. 使用调试器:跟踪调用栈

  5. 对比迭代版本:验证递归正确性

【扩展应用】

  1. 回溯算法:N皇后、数独求解

  2. 分治算法:最近点对、矩阵乘法

  3. 树形DP:树上动态规划

  4. 图遍历:深度优先搜索

  5. 函数式编程:递归是函数式编程的核心


1.2 网格DFS与BFS模板(课程04)

📦 核心代码模板

📊 搜索算法类型总结

算法类型数据结构适用场景特点
BFS队列最短路径、最少步数层次遍历,最先找到最短解
DFS栈/递归所有路径、连通性深度优先,可能找到非最短解
记忆化DFS递归+缓存滑雪、背包等优化问题避免重复计算,提高效率
状态BFS队列+状态集推箱子等复杂状态问题处理多维状态空间

📊 方向数组配置

移动类型方向数量dx数组dy数组适用问题
四方向4{0,0,1,-1}{1,-1,0,0}基本迷宫、连通块
八方向8{0,0,1,-1,1,1,-1,-1}{1,-1,0,0,1,-1,1,-1}包含对角线的移动
马走日8{-2,-2,-1,-1,1,1,2,2}{-1,1,-2,2,-2,2,-1,1}象棋中的马
自定义N根据问题定义根据问题定义特殊移动规则

📊 BFS与DFS对比

特性BFSDFS
数据结构队列栈/递归
空间复杂度O(宽)O(深)
找到的解最短解(无权)不一定最短
适用场景最短路径、最少步数所有路径、连通性
实现难度中等简单

📊 记忆化搜索应用

问题类型状态定义转移方程复杂度
滑雪问题dp[x][y]: 从(x,y)出发的最长路径dp[x][y]=1+max(dp[nx][ny])O(m×n)
01背包memo[i][j]: 前i个物品容量j的最大价值memo[i][j]=max(不选, 选)O(n×C)
完全背包memo[i][j]: 前i个物品容量j的最大价值memo[i][j]=max(不选, 选+递归)O(n×C)

📊 常见问题模式

问题模式推荐算法关键点例题
最短路径BFS层次遍历,记录步数马的遍历
连通块计数BFS/DFS遍历未访问点,标记整个区域细胞计数
最长递减路径DFS+记忆化记忆从每个点出发的最长路径滑雪问题
可达性检查BFS检查是否能从起点到终点迷宫连通
推箱子状态BFS(人位置,箱子位置)作为状态推箱子
传送迷宫BFS+特殊处理同时处理普通移动和传送传送迷宫

📊 关联题目索引

题目编号题目名称核心算法难度
B3625能否通过迷宫BFS连通性
P1443马的遍历BFS最短路径⭐⭐
P1825传送迷宫BFS+传送门⭐⭐⭐
LS1217推箱子1状态BFS⭐⭐⭐
LS1117滑雪DFS记忆化⭐⭐
LS108201背包递归记忆化⭐⭐
LS1083完全背包递归记忆化⭐⭐

【核心算法详解】**

1. BFS通用模板 (bfs_min_steps)

2. DFS记忆化模板 (dfs_ski)

3. 状态BFS模板 (push_box_min_steps)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:单点、不可达、边界情况

  3. 性能测试:100×100网格

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 功能扩展

【学习建议】

  1. 理解差异:掌握BFS和DFS的核心区别和适用场景

  2. 动手实现:亲自实现每种搜索算法

  3. 状态设计:学习如何设计复杂问题的状态表示

  4. 调试技巧:使用打印路径、状态等方法调试

【常见错误】

  1. 忘记标记访问:导致无限循环或重复访问

  2. 数组越界:方向移动时未检查边界

  3. 状态哈希冲突:自定义状态哈希函数不当

  4. 递归深度过大:DFS递归过深导致栈溢出

  5. 初始化错误:距离数组或访问数组初始化不当

【实用技巧】

  1. 可视化调试:打印网格和路径帮助理解

  2. 小数据测试:手动计算小数据验证算法

  3. 对拍测试:与简单算法对比结果

  4. 方向数组:使用方向数组简化代码

  5. 状态压缩:复杂状态使用位运算或编码压缩


二、动态规划模块

2.1 背包问题全家桶(课程10)

📦 核心代码模板

📊 背包问题类型总结

问题类型特征核心代码遍历顺序时间复杂度
01背包每个物品最多选一次dp[j] = max(dp[j], dp[j-w]+v)容量逆序O(n×C)
完全背包物品可选无限次dp[j] = max(dp[j], dp[j-w]+v)容量顺序O(n×C)
多重背包物品有数量限制二进制拆分后按01背包容量逆序O(n×log(k)×C)
分组背包每组只能选一个外层容量,内层组内物品容量逆序O(总物品数×C)
二维费用两种费用限制dp[j][k] = max(...)双重逆序O(n×C₁×C₂)
混合背包多种类型混合根据类型选择遍历顺序混合O(n×C)

📊 遍历顺序对比

背包类型物品循环容量循环顺序原理
01背包外层物品内层容量逆序防止同一物品被重复选择
完全背包外层物品内层容量顺序允许同一物品被多次选择
多重背包外层物品+拆分内层容量逆序拆分后变为01背包
分组背包外层组,内层物品外层容量逆序每组只能选一个

📊 初始化策略

问题要求dp[0]初始化其他位置初始化目的
最大价值00计算最大可能价值
恰好装满0-∞(负无穷)确保只有恰好装满才有效
方案计数10空背包是一种方案
最小物品数0∞(正无穷)求最小值

📊 优化技巧对比

优化技术适用场景效果实现复杂度
二进制拆分多重背包O(k)→O(logk)中等
单调队列多重背包O(n×C)困难
滚动数组所有背包空间降维简单
贪心剪枝搜索解法减少搜索空间中等

📊 常见问题变种

基础问题变种解法差异复杂度变化
最大价值恰好装满初始化不同不变
最大价值方案计数状态转移为累加不变
最大价值具体方案记录选择路径空间增加
01背包分组背包增加组约束不变
01背包依赖背包树形DPO(n×C²)

📊 关联题目索引

题目编号题目名称核心算法难度
LS108201背包基础模板
LS123201背包恰好装满初始化技巧⭐⭐
LS1083完全背包顺序遍历⭐⭐
LS1084多重背包二进制拆分⭐⭐⭐
LS1086二维费用背包二维DP⭐⭐⭐
LS1087分组背包组内约束⭐⭐⭐
LS1085混合背包类型混合⭐⭐⭐⭐
LS1088依赖背包树形DP⭐⭐⭐⭐

【核心算法详解】

1. 01背包核心 (knapsack_01_iterative)

2. 完全背包核心 (knapsack_complete_iterative)

3. 多重背包二进制拆分 (knapsack_multiple)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:空背包、单个物品、零容量等

  3. 性能测试:1000物品,10000容量

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 功能扩展

【学习建议】

  1. 掌握核心差异:理解01背包和完全背包遍历顺序的区别

  2. 从简到繁:先掌握01背包,再学其他变种

  3. 动手实现:亲自实现每种背包的代码

  4. 分析复杂度:理解各种优化技术的原理

【常见错误】

  1. 遍历顺序混淆:01背包用顺序或完全背包用逆序

  2. 初始化错误:恰好装满问题初始化不当

  3. 数组越界:容量循环边界条件错误

  4. 整数溢出:价值和容量很大时忘记用long long

  5. 多重背包超时:未使用二进制优化直接三重循环

【实用技巧】

  1. 打印DP表:调试时观察状态转移

  2. 小数据验证:手动计算小数据验证算法

  3. 对拍测试:与暴力搜索对比结果

  4. 模版化代码:封装通用背包函数

  5. 边界测试:测试空、单个、零容量等边界情况

 


2.2 线性DP与状态设计(课程12, 17)

📦 核心代码模板

📊 线性DP问题分类

问题类型状态维度典型问题时间复杂度空间复杂度
最大子数组和一维Kadane算法O(n)O(1)
最长递增子序列一维LIS问题O(n²)或O(nlogn)O(n)
环形最大和一维变种环形数组O(n)O(1)
最大两段和一维分解分割问题O(n)O(n)
最大子矩阵和二维降一维子矩阵问题O(m²n)O(n)
最长公共子序列二维LCS问题O(mn)O(min(m,n))
编辑距离二维字符串转换O(mn)O(min(m,n))

📊 状态设计模式总结

模式状态定义转移方程示例
以i结尾dp[i]: 以nums[i]结尾的解dp[i] = f(nums[i], dp[i-1])最大子数组和
前i个元素dp[i]: 前i个元素的解dp[i] = f(dp[i-1], 选择i)背包问题
二维状态dp[i][j]: 涉及两个序列dp[i][j] = f(dp[i-1][j], dp[i][j-1])LCS问题
环形处理两种情况考虑取max(正常,总和-最小)环形最大和

📊 优化技巧对比

技巧适用场景效果实现复杂度
滚动数组状态只依赖前一行/列空间降维简单
前缀和频繁查询子数组和查询O(1)简单
贪心+二分LIS等单调性问题时间O(nlogn)中等
分治思想环形、两段等问题分解为子问题中等
压缩状态状态数有限但组合多减少状态数复杂

📊 常见问题变种

基础问题变种解法差异复杂度变化
最大子数组和环形最大和两种情况取maxO(n)不变
最大子数组和最大两段和前后缀分解O(n),空间O(n)
最大子数组和最大k段和DP[i][j]状态O(nk)
LIS最长非递减子序列修改比较条件同O(nlogn)
LIS最长摆动序列维护两个状态O(n)

📊 关联题目索引

题目编号题目名称核心算法难度
LS1016最大子数组和Kadane算法
LS1250最大子数组和变体Kadane变种⭐⭐
LS1248最长递增子序列LIS DP⭐⭐
LS1251环形最大子数组和环形处理⭐⭐
LS1181最大两段子数组和前后缀分解⭐⭐⭐
P1121环状最大两段和环形两段处理⭐⭐⭐

【核心算法详解】

1. Kadane算法核心 (max_subarray_sum)

2. LIS贪心+二分 (lis_length_nlogn)

3. 环形最大和处理 (max_circular_subarray_sum)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:空数组、单元素、全负数等

  3. 性能测试:10万数据量,500×500矩阵

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 功能扩展

【学习建议】

  1. 掌握模板:记住Kadane、LIS、LCS等经典模板

  2. 理解状态:明确dp[i]dp[i][j]的含义

  3. 练习变种:从基础问题开始,逐步尝试变种

  4. 分析复杂度:理解时间和空间复杂度来源

【常见错误】

  1. 边界初始化:dp[0]或dp[1]初始化错误

  2. 索引处理:0-indexed与1-indexed混淆

  3. 负数处理:最大乘积等问题忘记处理负数

  4. 环形处理:忘记特殊情况(全负数)

  5. 空间优化:滚动数组更新顺序错误

【实用技巧】

  1. 可视化DP表:打印DP表帮助理解状态转移

  2. 手动模拟:小数据手动计算验证算法

  3. 对拍测试:与暴力解法对比结果

  4. 分步调试:复杂DP问题分步实现和测试

  5. 模版化代码:封装通用DP函数,便于复用

 


2.3 股票买卖系列(课程17)

📦 核心代码模板

📊股票问题状态设计

  1. 一次交易:记录历史最低价

  2. 无限交易:贪心,所有上涨都交易

  3. 两次交易:前后缀分解

  4. k次交易:三维DP

  5. 含冷冻期:三个状态的状态机

  6. 含手续费:卖出时扣除

📊关联题目

 

【各算法时间复杂度对比】

算法时间复杂度空间复杂度适用场景
一次交易O(n)O(1)只能买卖一次
无限交易O(n)O(1)可以无限次买卖
两次交易O(n)O(n)最多买卖两次
k次交易O(n×k)O(k)最多买卖k次
含冷冻期O(n)O(1)卖出后有一天不能买
含手续费O(n)O(1)每次交易有手续费

【核心算法详解】

【1】一次交易 (max_profit_one_transaction)

 

【2】无限交易 (max_profit_unlimited_transactions)

 

【3】k次交易 (max_profit_at_most_k)

 

【4】含冷冻期 (max_profit_with_cooldown)

 

【5】测试用例设计

代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:递减序列、递增序列

  3. 复杂测试:波动序列

  4. 性能测试:10万数据量测试

  5. 交互测试:用户自定义输入

【6】扩展与优化

【6.1】空间优化

所有算法都实现了空间优化版本:

【6.2】通用解法

max_profit_general() 函数支持所有参数:

【6.3】错误处理

【7】学习建议

  1. 从简单到复杂:先理解一次交易,再学无限交易,最后学k次交易

  2. 状态机思维:将买卖问题转化为状态转移

  3. 空间优化技巧:滚动数组、变量复用

  4. 测试驱动:自己设计测试用例验证理解

【8】常见错误

  1. 边界条件:n<2时返回0

  2. 初始化:DP数组正确初始化

  3. 状态转移:确保所有情况都考虑到

  4. 整数溢出:使用LLONG_MIN/2作为负无穷


三、数据结构模块

3.1 STL核心用法(课程3)

📦 核心代码模板

📊 STL容器选择指南

容器特性时间复杂度适用场景
vector动态数组,随机访问尾插O(1),中间O(n)需要随机访问,尾部操作频繁
deque双端队列,双向开口头尾O(1),中间O(n)需要双端操作,随机访问
list双向链表,任意插入插入删除O(1),查找O(n)频繁在任意位置插入删除
set红黑树,有序唯一所有操作O(logn)需要有序且唯一的集合
map键值对,有序唯一所有操作O(logn)需要有序映射
unordered_set哈希表,无序唯一平均O(1),最坏O(n)需要快速查找,不关心顺序
unordered_map哈希表,无序映射平均O(1),最坏O(n)需要快速键值查找
priority_queue堆,优先队列push/pop O(logn),top O(1)需要获取最大/最小值
stack栈,LIFO所有操作O(1)后进先出场景
queue队列,FIFO所有操作O(1)先进先出场景

📊 迭代器分类与能力

迭代器类型前进后退随机访问典型容器
输入istream
输出ostream
前向forward_list
双向list, set, map
随机访问vector, deque, array

📊 常用算法时间复杂度

算法时间复杂度说明
sortO(nlogn)快速排序或内省排序
stable_sortO(nlogn)归并排序,稳定
nth_elementO(n)找到第n大元素
binary_searchO(logn)二分查找(需要已排序)
findO(n)线性查找
lower_boundO(logn)下界查找(需要已排序)
uniqueO(n)去重(需要已排序)
reverseO(n)反转
accumulateO(n)累加
next_permutationO(n)下一个排列

📊 STL使用场景总结

需求推荐容器理由
需要排序/二分查找set/map自动排序,查找O(logn)
需要快速查找unordered_set/unordered_map平均O(1)查找
需要最大/最小值priority_queue堆操作高效
需要双端操作deque头尾操作都是O(1)
需要随机访问vector下标访问O(1)
需要任意位置插入删除list链表操作O(1)
需要LIFOstack栈语义清晰
需要FIFOqueue队列语义清晰
需要字符串操作string专用字符串功能

📊 易错点与注意事项

易错点正确做法说明
map[]创建不存在的key使用find或count检查mp["key"]会自动创建
vector中间插入删除考虑list或deque中间操作O(n)
priority_queue默认大顶堆使用greater创建小顶堆注意比较函数方向
迭代器失效更新后重新获取迭代器插入删除可能使迭代器失效
未排序使用binary_search先sort再binary_search二分查找需要有序
内存泄漏使用智能指针unique_ptr/shared_ptr自动管理
字符串查找失败检查返回值是否为nposfind失败返回string::npos

📊 关联题目索引

题目编号题目名称核心STL难度
LS1033向量基础vector
LS1038向量操作vector算法⭐⭐
LS1039集合与映射set/map⭐⭐
LS1034去除重复set/unique⭐⭐
LS1212排序规则自定义排序⭐⭐⭐
LT3556字符串处理string⭐⭐

【STL核心要点】

方面关键点示例
容器选择根据操作需求选择查找多用unordered,排序多用set
迭代器理解不同迭代器能力vector支持随机访问,list只支持双向
算法配合迭代器使用sort(vec.begin(), vec.end())
字符串丰富的成员函数find, substr, replace
智能指针自动内存管理unique_ptr, shared_ptr

【学习建议】

  1. 理解原理:掌握各种容器的内部实现原理

  2. 熟练常用操作:vector的push_back,map的find等

  3. 掌握算法:sort, find, accumulate等常用算法

  4. 理解迭代器:不同容器的迭代器能力和失效规则

  5. 实践应用:多写代码,解决实际问题

【常见错误】

  1. 迭代器失效:修改容器后继续使用旧迭代器

  2. map[]自动创建:使用find或count检查是否存在

  3. 未排序使用二分查找:先调用sort

  4. 字符串查找失败:检查返回值是否为npos

  5. 内存泄漏:忘记释放动态分配的内存

【性能优化】

  1. 预留空间:vector.reserve()减少扩容开销

  2. 移动语义:使用std::move避免不必要的拷贝

  3. 选择合适算法:根据数据规模选择算法

  4. 避免重复计算:缓存计算结果

  5. 使用emplace:直接构造,避免拷贝

【实用技巧】

  1. 结构化绑定:C++17的auto [key, value]语法

  2. 范围for:简化容器遍历

  3. lambda表达式:编写简洁的比较函数

  4. 类型推导:使用auto简化类型声明

  5. 异常安全:使用RAII管理资源

【调试技巧】

  1. 打印容器:编写通用打印函数

  2. 使用assert:检查不变量

  3. 小数据测试:验证算法正确性

  4. 边界测试:测试空容器、极端值

  5. 性能分析:使用工具分析热点代码


3.2 树状数组(BIT)模板(课程7)

📦 核心代码模板

📊 BIT核心思想

概念公式说明
lowbitx & -x获取x最低位的1
管理区间(x-lowbit(x), x]tree[x]管理的范围
更新操作idx += lowbit(idx)向上更新父节点
查询操作idx -= lowbit(idx)向下累加子节点
下标必须从1开始0的lowbit为0,会死循环

📊 BIT时间复杂度分析

操作时间复杂度说明
单点更新O(logn)最坏情况需要更新所有祖先节点
前缀查询O(logn)最坏情况需要累加所有子节点
区间查询O(logn)两次前缀查询
建树O(nlogn)逐个插入
高效建树O(n)使用前缀和建树
区间更新O(logn)差分思想

📊 BIT vs 线段树对比

特性树状数组 (BIT)线段树 (Segment Tree)选择建议
代码复杂度BIT更易实现
空间复杂度O(n)O(4n)BIT更省空间
功能范围主要求和全面(求和、最值、区间修改等)线段树更强大
扩展性有限线段树更灵活
常数因子较大BIT更快
学习曲线简单较难BIT更易掌握
适用场景前缀和、逆序对复杂区间查询根据需求选择

📊 BIT变体与应用

变体类型功能实现方式应用场景
基础BIT单点更新,区间查询一个树状数组P3374
差分BIT区间更新,单点查询维护差分数组P3368
双BIT区间更新,区间查询两个树状数组P3372
二维BIT二维矩阵操作二维扩展子矩阵求和
最值BIT区间最值(有限制)特殊更新规则特定问题
权值BIT第k小元素维护频次数组动态排名

📊 关联题目索引

题目编号题目名称核心算法难度
P3374树状数组1单点更新区间查询⭐⭐
P3368树状数组2区间更新单点查询⭐⭐
P3372线段树1区间更新区间查询⭐⭐⭐
P1908逆序对离散化+BIT⭐⭐⭐
LS1104差分与前缀和BIT应用⭐⭐
P2068统计和二维BIT应用⭐⭐⭐
P1972HH的项链BIT+离线查询⭐⭐⭐⭐

【算法特点】

BIT类型特点适用场景
基础BIT简单高效单点更新,区间查询
差分BIT区间更新优化区间加,单点查
双BIT功能全面区间加,区间查
二维BIT矩阵操作子矩阵求和
权值BIT动态排名第k小,逆序对

【学习建议】

  1. 理解原理:掌握lowbit操作和管理区间概念

  2. 熟练模板:熟记update和query的标准实现

  3. 掌握变体:学习差分、双BIT等扩展

  4. 问题转化:学会将实际问题转化为BIT问题

  5. 对比学习:与线段树对比,理解各自优缺点

【常见错误】

  1. 下标从0开始:BIT必须从1开始

  2. 忘记lowbit:使用 x & -x 而非其他计算

  3. 边界检查:查询时确保1 ≤ l ≤ r ≤ n

  4. 溢出问题:大量更新时使用i64防止溢出

  5. 离散化错误:处理重复元素时要注意

【扩展应用】

  1. 三维BIT:空间中的立方体查询

  2. 带删除BIT:支持删除操作的动态集合

  3. BIT套数据结构:BIT套平衡树等

  4. 离线处理:结合排序处理复杂查询

  5. 可持久化BIT:支持历史版本查询

【性能优化】

  1. O(n)建树:使用前缀和初始化

  2. 内存优化:动态分配或使用vector

  3. 缓存优化:顺序访问提高缓存命中率

  4. 编译优化:使用O2优化级别

  5. 输入优化:使用快速输入输出

【实用技巧】

  1. 二进制跳转:快速找到第k小元素

  2. 离散化模板:统一处理大数据值域

  3. 调试输出:打印tree数组观察状态

  4. 对拍测试:与暴力算法对比验证

  5. 内存池:预分配内存提高性能


3.3 线段树模板(课程13)

📦 核心代码模板

线段树核心概念

线段树时间复杂度

线段树应用场景

  1. 区间和/最大值/最小值查询

  2. 区间更新(加减、赋值等)

  3. 区间统计(满足条件的元素个数)

  4. 区间合并问题

关联题目


四、图论算法模块

4.1 最短路算法(课程05)

📦 核心代码模板

📊 最短路算法选择指南

算法时间复杂度空间复杂度适用场景限制
Dijkstra(堆)O((V+E)logV)O(V+E)非负权图,单源最短路不能处理负权边
Dijkstra(矩阵)O(V²)O(V²)稠密图,非负权图不能处理负权边
Bellman-FordO(VE)O(V+E)负权图,检测负环效率较低
SPFA平均O(kE),最坏O(VE)O(V+E)负权图,随机图网格图可能退化为O(VE)
FloydO(V³)O(V²)多源最短路,任意图只能处理小规模图
分层DijkstraO(k(V+E)logV)O(kV+kE)有k次特殊机会状态空间扩大k倍
双向DijkstraO((V+E)logV)O(V+E)单源单目标最短路需要反向图
A*O(kElogV)O(V+E)第k短路需要良好启发函数

📊 算法特性对比

特性DijkstraBellman-FordSPFAFloyd
负权边
负环检测
最优性贪心最优动态规划Bellman-Ford优化动态规划
实现难度简单中等中等简单
稳定性稳定稳定不稳定稳定
适用图类型非负权图任意图稀疏图任意图

📊 常见问题与算法选择

问题类型推荐算法理由
单源非负权最短路Dijkstra(堆)效率最高,实现简单
单源含负权最短路SPFA平均效率高,实现简单
负环检测SPFA或Bellman-FordSPFA更快,Bellman-Ford更稳定
多源最短路Floyd代码简单,小图适用
大图多源最短路多次Dijkstra当V较小时优于Floyd
有特殊限制的最短路分层图通过状态扩展处理限制
不等式组求解Bellman-Ford转化为最短路问题
第k短路A*算法结合启发式搜索

📊 关联题目索引

题目编号题目名称核心算法难度
P4779Dijkstra模板Dijkstra(堆)⭐⭐
P3385负环检测SPFA/Bellman-Ford⭐⭐
P4568飞行路线分层图最短路⭐⭐⭐
P5960差分约束Bellman-Ford⭐⭐⭐
P1629邮递员送信往返最短路⭐⭐
LS1095旅游巴士最短路+时间限制⭐⭐⭐
P1462通往奥格瑞玛的道路最短路+二分⭐⭐⭐
P2865路障次短路⭐⭐⭐

【算法特点】

算法特点适用场景
Dijkstra高效,非负权常规最短路问题
SPFA灵活,可处理负权含负权边的图
Floyd简单,多源小规模多源最短路
分层图处理特殊限制有k次机会的问题
双向搜索优化单源单目标已知起点和终点

【学习建议】

  1. 理解原理:掌握各种算法的核心思想

  2. 熟练模板:熟记常用算法的标准实现

  3. 对比分析:理解不同算法的优缺点

  4. 问题转化:学会将实际问题转化为最短路问题

  5. 优化技巧:学习各种优化方法

【常见错误】

  1. 负权边使用Dijkstra:会导致错误结果

  2. 忘记初始化距离:导致不可预测行为

  3. 优先级队列误用:使用大顶堆而非小顶堆

  4. Floyd三重循环顺序错误:k必须在最外层

  5. 内存溢出:邻接矩阵过大导致内存不足

【扩展应用】

  1. 次短路:记录次优距离

  2. k短路:A*算法或Yen算法

  3. 最小环:Floyd变形

  4. 最小生成树与最短路结合:综合问题

  5. 动态最短路:边权随时间变化

【性能优化】

  1. 数据结构优化:使用vector代替list

  2. 内存优化:使用一维数组表示邻接矩阵

  3. 算法选择:根据图特性选择合适算法

  4. 输入优化:使用快速输入输出

  5. 并行计算:多线程处理不同部分

【实用技巧】

  1. 虚拟节点:处理特殊约束

  2. 状态压缩:将额外信息编码到状态中

  3. 预处理:提前计算常用信息

  4. 剪枝优化:提前终止不可能的分支

  5. 验证方法:用不同算法互相验证


4.2 最小生成树与并查集(课程21)

📦 核心代码模板

📊 Kruskal vs Prim对比

特性Kruskal算法Prim算法适用场景
思想贪心选边贪心加点-
数据结构并查集 + 排序优先队列 + 邻接表-
时间复杂度O(ElogE)O(ElogV)-
空间复杂度O(V+E)O(V+E)-
适合图类型稀疏图稠密图边少用Kruskal,点多用Prim
实现难度简单中等-
需要预处理边排序构建邻接表-
稳定性稳定(基于排序)不稳定(优先队列)-

📊 并查集优化技巧

优化技术实现方式效果
路径压缩find(x)中 parent[x] = find(parent[x])摊还O(α(n))
按秩合并小树合并到大树,rank记录高度保持树平衡
维护大小size数组记录集合元素个数支持大小查询
带权并查集维护节点到根的距离解决更多问题

📊 最小生成树变体问题

问题类型描述解法相关题目
标准MST最小化边权总和Kruskal/PrimLS1276
最大生成树最大化边权总和Kruskal逆序-
最小比率树最小化∑cost/∑profit分数规划+二分LS1272
瓶颈生成树最小化最大边权MST的最大边P1396
买礼物问题直接买或优惠买虚拟节点P1194
逐个击破最小化摧毁边权和逆向思维P2700
次小生成树权值第二小的生成树MST+LCA-

📊 关联题目索引

题目编号题目名称核心算法难度
LS1276最小生成树Kruskal模板⭐⭐
P1551亲戚并查集基础
P1194买礼物虚拟节点+MST⭐⭐
P1396营救最大边最小化⭐⭐
P2700逐个击破并查集+逆向思维⭐⭐⭐
LS1272最小比率生成树分数规划+MST⭐⭐⭐⭐

📊 算法性能对比

数据规模Kruskal时间Prim时间内存使用
V=1000, E=10000~10ms~15ms~1MB
V=10000, E=100000~100ms~200ms~10MB
V=50000, E=200000~500ms~1s~50MB
V=100000, E=500000~1.5s~3s~100MB

 

 

【算法特点】

算法特点适用场景
DSU高效维护连通性动态连通性问题
Kruskal实现简单,适合稀疏图边较少的无向图
Prim适合稠密图,邻接表友好点较少的无向图
分数规划解决比值优化问题最小比率生成树

【学习建议】

  1. 理解原理:掌握贪心思想在MST中的应用

  2. 熟练模板:熟记Kruskal和Prim的标准实现

  3. 掌握优化:理解并查集的路径压缩和按秩合并

  4. 问题转化:学会将实际问题转化为MST问题

  5. 对比分析:比较不同算法的适用场景

【常见错误】

  1. 忘记排序:Kruskal需要先对边排序

  2. 图不连通:没有检查是否形成完整生成树

  3. 数据类型:权值求和可能溢出,使用i64

  4. 节点编号:确认是0-indexed还是1-indexed

  5. 重复边:处理重边时选择最小权值

【扩展应用】

  1. 次小生成树:枚举替换MST中的边

  2. 度限制生成树:某些节点有度数限制

  3. 有向图最小树形图:朱刘算法

  4. 斯坦纳树:包含指定节点的最小连通子图

  5. k度限制生成树:节点度数不超过k

【性能优化】

  1. 并查集优化:路径压缩 + 按秩合并

  2. 优先队列优化:使用pair或自定义比较器

  3. 内存优化:使用vector代替list

  4. 算法选择:根据图密度选择合适算法

  5. 输入优化:使用快速输入输出

【实用技巧】

  1. 虚拟节点:处理特殊约束

  2. 逆向思维:从目标状态反推

  3. 离线处理:先读入所有数据再处理

  4. 调试技巧:用小数据验证,打印中间结果

  5. 验证方法:用两种算法互相验证


五、高级算法模块

5.1 数论分块(课程15, 19)

📦 核心代码模板

📊 数论分块原理

关键点说明时间复杂度
核心思想floor(n/i) 只有 O(√n) 种不同的值-
区间计算相同值的区间 [l, r] 一起计算,其中 r = n / (n / l)O(√n)
优化效果从 O(n) 优化到 O(√n)降低两个数量级

📊 常用数论公式

公式数学表达应用场景
基础分块∑_{i=1}^{n} floor(n/i)LS1261
加权分块∑_{i=1}^{n} floor(n/i) * iLS1230
余数求和{i=1}^{n} (k mod i) = nk - ∑{i=1}^{n} floor(k/i) * iP2261
GCD求和{i=1}^{n} ∑{j=1}^{n} gcd(i,j) = ∑_{d=1}^{n} φ(d) * floor(n/d)²P2398
莫比乌斯反演∑_{d|n} μ(d) = [n=1]数论函数转换

📊 欧拉函数性质

性质公式/说明应用
定义φ(n):1~n中与n互质的数的个数基础概念
积性函数若 gcd(a,b)=1,则 φ(ab) = φ(a)φ(b)分治计算
计算公式φ(n) = n × ∏_{p|n} (1 - 1/p)求值公式
质数性质φ(p) = p-1,φ(p^k) = p^k - p^{k-1}特殊情况
求和性质∑_{d|n} φ(d) = n莫比乌斯反演

📊 数论分块时间复杂度分析

问题类型暴力复杂度分块复杂度优化倍数
基础分块O(n)O(√n)O(√n)倍
二维分块O(n²)O(n)O(n)倍
GCD求和O(n²)O(n)O(n)倍
余数求和O(n)O(√k)O(√n)倍

📊 关联题目索引

题目编号题目名称核心算法难度
LS1261数论分块基础数论分块⭐⭐
LS1262多维数论分块二维数论分块⭐⭐⭐
P2261余数求和数论分块应用⭐⭐
P2398GCD求和欧拉函数+数论分块⭐⭐⭐
LS1230简洁的数学加权数论分块⭐⭐

【算法特点】

算法特点适用场景
基础分块最简单,理解数论分块原理教学、入门
加权分块结合等差数列求和加权求和问题
余数求和实际应用,转化技巧数学问题
GCD求和综合性强,需要预处理数论综合题
莫比乌斯高级数论工具反演、筛选

【学习建议】

  1. 理解原理:先理解为什么 floor(n/i) 只有 O(√n) 种值

  2. 掌握模板:熟练使用数论分块的标准模板

  3. 学会转化:将复杂问题转化为数论分块可解的形式

  4. 结合数学:掌握欧拉函数、莫比乌斯函数等数论知识

  5. 实践验证:用小数据暴力验证算法正确性

【常见错误】

  1. 边界溢出:忘记使用 i64,导致 int 溢出

  2. 循环条件:忘记处理 k < l 的情况

  3. 区间计算:等差数列求和公式写错

  4. 预处理错误:欧拉函数或莫比乌斯函数计算错误

  5. 复杂度估计:误以为所有数论分块都是 O(√n)

【扩展应用】

  1. 三维分块:∑∑∑ floor(n/i)floor(m/j)floor(k/l)

  2. 带函数分块:∑ f(floor(n/i)) * g(i)

  3. 前缀和优化:预处理前缀和加速区间求和

  4. 积性函数:结合积性函数性质进一步优化

【性能对比】

数据规模暴力算法数论分块加速倍数
n=10^3~1ms~0.01ms~100倍
n=10^4~10ms~0.05ms~200倍
n=10^5~100ms~0.2ms~500倍
n=10^6~1s~1ms~1000倍
n=10^7~10s~3ms~3000倍

【实用技巧】

  1. 可视化理解:画出 floor(n/i) 随 i 变化的图像

  2. 对拍测试:与小数据暴力解法对比结果

  3. 模运算处理:涉及模运算时注意取模时机

  4. 记忆化搜索:对重复查询的结果进行缓存

  5. 分段处理:对大数据采用分段预处理策略


5.2 筛法(课程14)

📦 核心代码模板

📊 筛法对比

筛法类型时间复杂度空间复杂度特点适用场景
埃氏筛O(nloglogn)O(n)简单易实现,常数小n ≤ 10⁷
欧拉筛O(n)O(n)线性时间,每个数只筛一次n ≤ 10⁷,需要线性时间
区间筛O((r-l)loglogr)O(√r + r-l)处理大区间,内存友好r-l ≤ 10⁶, r ≤ 10¹²
积性函数筛O(n)O(n)同时计算多种积性函数需要多个积性函数值

📊 积性函数筛法

函数符号定义筛法公式
欧拉函数φ(n)1~n中与n互质的数的个数φ(p^k) = p^k - p^{k-1}
约数个数d(n)n的正因子个数d(p^k) = k+1
约数和σ(n)n的所有正因子之和σ(p^k) = (p^{k+1}-1)/(p-1)
莫比乌斯函数μ(n)数论反演函数μ(1)=1, μ(p)=-1, μ(p²)=0

📊 积性函数公式总结

函数公式说明
欧拉函数φ(n) = n × ∏_{p|n} (1 - 1/p)乘积形式
约数个数d(n) = ∏{i=1}^k (αi + 1)n = ∏ p_i^{α_i}
约数和σ(n) = ∏{i=1}^k (1 + p_i + p_i² + ... + p_i^{αi})等比数列求和
莫比乌斯函数μ(n) = 1 (n=1), (-1)^k (n无平方因子), 0 (其他)定义式

📊 算法性能对比

数据规模埃氏筛时间欧拉筛时间加速比内存使用
n=10⁶~10ms~20ms0.5×~1MB
n=10⁷~100ms~200ms0.5×~10MB
n=10⁸~1s~2s0.5×~100MB
n=10⁹内存不足内存不足-~1GB

📊 关联题目索引

题目编号题目名称核心算法难度
LS1163埃氏筛和欧拉筛基础筛法⭐⭐
LS1236区间筛法大区间质数筛选⭐⭐⭐
LS1164约数个数、约数和、欧拉函数积性函数筛法⭐⭐⭐
LS1231连续的自然数筛法应用⭐⭐
LS1237最大公约数计数欧拉函数应用⭐⭐⭐

【算法特点】

算法特点适用场景
埃氏筛实现简单,常数小快速获取质数列表
欧拉筛线性时间,可扩展需要积性函数或线性时间
区间筛内存友好,处理大数大区间质数筛选
积性函数筛多功能,效率高需要多种数论函数

【学习建议】

  1. 理解原理:先理解筛法的基本思想(标记倍数)

  2. 对比学习:比较埃氏筛和欧拉筛的区别

  3. 掌握优化:学习各种筛法的优化技巧

  4. 实践应用:解决实际问题,理解筛法的应用场景

  5. 扩展思考:思考如何筛其他数论函数

【常见错误】

  1. 边界溢出:ii 可能溢出,需要判断 ii <= n

  2. 内存不足:使用 vector 而非 vector 节省内存

  3. 区间计算:区间筛法的起始点计算错误

  4. 质数判断:忘记处理 0 和 1 不是质数

  5. 数据类型:使用 int 导致大数溢出

【扩展应用】

  1. 质数间隔:计算相邻质数的最大间隔

  2. 质数分布:研究质数在不同区间的分布

  3. 质数测试:结合筛法实现 Miller-Rabin 测试

  4. 因数分解:利用筛法预处理进行快速质因数分解

  5. 数论函数:计算更多的积性函数(如 Liouville 函数)

【性能优化】

  1. 内存优化:使用 bitset 进一步减少内存

  2. 分段筛法:对超大范围使用分段处理

  3. 并行计算:多线程并行筛不同区间

  4. 缓存优化:利用 CPU 缓存局部性

  5. 编译优化:使用编译器优化选项

【实用技巧】

  1. 预计算:预先计算常用范围内的筛法结果

  2. 惰性计算:需要时才计算,节省内存

  3. 混合方法:小范围用筛法,大范围用概率方法

  4. 验证测试:用小数据暴力验证算法正确性

  5. 性能分析:使用性能分析工具优化热点代码

 


5.3 数学与数论(课程06, 14)

📦 核心代码模板

📊 算法复杂度总结

算法时间复杂度空间复杂度适用场景
快速幂O(log n)O(1)大指数取模
矩阵快速幂O(k³ log n)O(k²)线性递推加速
扩展欧几里得O(log min(a,b))O(log min(a,b))求解不定方程
中国剩余定理O(n log M)O(n)同余方程组
组合数预处理O(n)预处理,O(1)查询O(n)频繁组合数查询
质因数分解O(√n)O(log n)单个数分解
埃氏筛O(n log log n)O(n)素数筛选
欧拉筛O(n)O(n)高效素数筛选
欧拉函数O(√n)O(1)单个φ(n)计算
预处理φ数组O(n)O(n)批量φ(n)计算
数论分块O(√n)O(1)∑ floor(n/i) 类求和

📊 数学公式与定理

名称公式/定理应用
快速幂a^b = (a(b/2))2(b偶)大数取模
矩阵快速幂F(n) = M^(n-1) × F(1)线性递推
扩展欧几里得ax + by = gcd(a,b)模逆元、同余方程
中国剩余定理x ≡ a_i (mod m_i) → 唯一解模M同余方程组
组合数C(n,k) = n!/(k!(n-k)!)计数问题
质因数分解n = ∏ p_i^{α_i}因数、gcd、lcm
欧拉函数φ(n) = n ∏ (1 - 1/p_i)模幂简化
欧拉定理a^φ(m) ≡ 1 (mod m), gcd(a,m)=1模运算简化
费马小定理a^(p-1) ≡ 1 (mod p), p为质数模逆元快速计算
卢卡斯定理C(n,k) ≡ ∏ C(n_i,k_i) (mod p)大组合数模小质数

📊 素数筛法对比

筛法时间复杂度空间复杂度特点
试除法O(√n)每个数O(1)单个数判断
埃氏筛O(n log log n)O(n)简单,易实现
欧拉筛O(n)O(n)线性,每个数只筛一次
分段筛O((R-L) log log R)O(√R + R-L)大范围[L,R]筛选

📊 组合数计算方法

方法时间复杂度适用条件特点
直接计算O(k)k较小简单,无预处理
阶乘预处理O(n)预处理,O(1)查询n≤10⁶, p为质数查询快
卢卡斯定理O(p log_p n)p较小,p为质数处理n>p的情况
递推公式O(n²)需要所有C(n,k)杨辉三角

📊 数论分块技巧

求和类型暴力复杂度分块复杂度优化倍数
∑ floor(n/i)O(n)O(√n)√n倍
∑ floor(n/i)*iO(n)O(√n)√n倍
∑ floor(n/i)*f(i)O(n)O(√n)(需前缀和)√n倍

📊 关联题目索引

题目编号题目名称核心算法难度
LS1024计算乘方和快速幂+等比求和⭐⭐
LS1156斐波那契数列矩阵快速幂⭐⭐
LS1161高阶斐波那契高阶矩阵快速幂⭐⭐⭐
LS1220扩展欧几里得模逆元、同余方程⭐⭐⭐
LS1233质因数分解试除法、最小质因子⭐⭐

【核心算法详解】

1. 快速幂核心 (fast_pow)

2. 矩阵快速幂斐波那契 (fibonacci_matrix)

3. 扩展欧几里得 (extended_gcd)

4. 组合数预处理 (Combinatorics)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:零、一、负数等边界

  3. 性能测试:大数、大数据量

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 算法优化

2. 功能扩展

3. 应用扩展

【学习建议】

  1. 理解数学原理:先理解背后的数学公式和定理

  2. 掌握核心模板:熟记快速幂、扩展欧几里得等模板

  3. 练习变种问题:从简单问题开始,逐步挑战复杂问题

  4. 分析复杂度:理解各种算法的时间空间复杂度

【常见错误】

  1. 模运算错误:忘记取模或取模位置错误

  2. 整数溢出:中间结果超出数据类型范围

  3. 边界条件:零、一、负数等特殊情况处理

  4. 质数判断:误判质数或合数

  5. 逆元不存在:在gcd(a,m)≠1时求逆元

【实用技巧】

  1. 模运算性质: (a+b)%m = ((a%m)+(b%m))%m

  2. 费马小定理:质数模数下快速求逆元

  3. 欧拉定理:非质数模数下简化幂运算

  4. 卢卡斯定理:大组合数模小质数

  5. 数论分块:高效计算∑ floor(n/i)类求和

 


5.4 贡献思维与单调栈(课程16)

📦 核心代码模板

📊 单调栈类型总结

类型单调性解决的问题示例
递增栈栈底到栈顶递增第一个更小元素、最小值贡献柱状图最大矩形
递减栈栈底到栈顶递减第一个更大元素、最大值贡献每日温度问题
严格递增严格递增避免重复计算最小值子数组最小值之和
非严格递增非严格递增包含相等元素特定问题边界处理

📊 贡献法公式总结

问题贡献公式说明
最小值之和Σ arr[i] × (i-left) × (right-i)left: 左边第一个更小,right: 右边第一个更小
最大值之和Σ arr[i] × (i-left) × (right-i)left: 左边第一个更大,right: 右边第一个更大
边界处理left=-1,right=n表示没有更小/更大的元素
相等元素一边严格,一边非严格避免重复计算或漏算

📊 单调队列维护规则

队列类型维护规则队头元素解决的问题
递减队列新元素比队尾大时弹出队尾当前最大值滑动窗口最大值
递增队列新元素比队尾小时弹出队尾当前最小值滑动窗口最小值
过期检查队头下标 ≤ i-k 时弹出-保持窗口大小

📊 常见问题模式与解法

问题模式关键点算法时间复杂度
下一个更大/更小单调栈+遍历方向单调栈O(n)
左右边界确定两次单调栈遍历单调栈O(n)
贡献法计算确定范围+乘法原理贡献法O(n)
滑动窗口最值单调队列+过期处理单调队列O(n)
二维问题转化逐行降维+单调栈降维+单调栈O(m×n)
循环数组处理扩展数组或遍历两遍循环处理O(n)

📊 关联题目索引

题目编号题目名称核心算法难度
LS1199柱状图最大矩形单调栈求边界⭐⭐
LS1247接雨水单调栈或双指针⭐⭐
LS1244子数组最小值之和贡献法⭐⭐⭐
LS1245子数组最值之差贡献法相减⭐⭐⭐
P1886滑动窗口最大值单调队列⭐⭐
P1725琪露诺的算术教室单调队列优化DP⭐⭐⭐
LS1200最大矩形逐行+单调栈⭐⭐⭐

【各算法时间复杂度对比】

算法时间复杂度空间复杂度适用场景
下一个更大元素O(n)O(n)温度、股价等序列
柱状图最大矩形O(n)O(n)直方图、矩阵问题
接雨水(单调栈)O(n)O(n)地形储水问题
接雨水(双指针)O(n)O(1)空间优化版
子数组最小值之和O(n)O(n)贡献法统计问题
滑动窗口最值O(n)O(k)固定窗口最值查询
最大矩形O(m×n)O(n)二维01矩阵

【核心算法详解】

1. 单调栈框架 (next_greater_element)

2. 贡献法核心 (sum_of_subarray_minimums)

3. 单调队列维护 (sliding_window_max)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:空数组、单个元素、重复元素

  3. 性能测试:10万数据量,1000×1000矩阵

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 边界处理技巧

【学习建议】

  1. 理解单调性:画图理解栈内元素单调性的维护

  2. 掌握模板:记住单调栈、单调队列的通用模板

  3. 贡献法思维:从枚举子数组转变为计算每个元素的贡献

  4. 二维降一维:掌握将二维问题转化为一维问题的技巧

【常见错误】

  1. 索引混淆:0-indexed与1-indexed混用

  2. 边界条件:left/right的初始值设置错误

  3. 相等处理:严格与非严格比较选择不当

  4. 模运算:忘记取模或模运算错误

  5. 过期检查:单调队列忘记检查队头是否过期

【实用技巧】

  1. 可视化调试:打印栈/队列内容观察变化

  2. 小数据验证:手工计算小数据验证算法

  3. 对拍测试:与暴力解法对比结果

  4. 复杂度证明:理解为什么每个元素只入栈出栈一次

  5. 模版化代码:封装通用函数,便于复用和调试

 


5.5 前缀和与差分(课程20)

📦 核心代码模板

📊 前缀和与差分总结

类型核心思想时间复杂度空间复杂度适用场景
一维前缀和pre[i]=Σnums[0..i-1]构造O(n),查询O(1)O(n)区间和查询
哈希优化前缀和记录前缀和出现情况O(n)O(n)特定和子数组统计
异或前缀和利用异或性质O(n)O(n)异或值子数组统计
二维前缀和二维累加和构造O(mn),查询O(1)O(mn)子矩阵和查询
一维差分端点操作代替区间更新更新O(1),重建O(n)O(n)区间加操作
二维差分容斥原理处理矩形更新O(1),重建O(mn)O(mn)子矩阵加操作

📊 异或运算性质

性质公式说明
自反性a ⊕ a = 0相同数异或为0
零元性a ⊕ 0 = a与0异或不变
交换律a ⊕ b = b ⊕ a可交换顺序
结合律(a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)可任意结合
区间异或xor[l..r] = pre[r+1] ⊕ pre[l]前缀异或差值

📊 常见问题模式

模式关键点算法时间复杂度
和为K的子数组寻找pre[j]-pre[i]=k前缀和+哈希表O(n)
最长和为0子数组0→-1,1→1前缀和+首次出现记录O(n)
异或子数组利用异或性质异或前缀+哈希表O(n)
平衡子串统计0/1数量相等前缀和+哈希表O(n)
子矩阵查询二维累加和二维前缀和O(1)查询
区间更新查询端点操作优化差分数组O(1)更新

📊 关联题目索引

题目编号题目名称核心算法难度
LS1265连续数组(0视为-1)前缀和+哈希表⭐⭐
LS1264异或子数组异或前缀+哈希表⭐⭐
LS1267最长平衡子串前缀和+哈希表⭐⭐
LS1266平衡子串变体前缀和+哈希表⭐⭐
LS1268异或序列异或前缀+查询⭐⭐⭐
LS1269维护数组差分+前缀和⭐⭐⭐
LS1270负载平衡二维前缀和分割⭐⭐⭐⭐
P14253旅行问题前缀和优化DP⭐⭐⭐⭐

【核心算法详解】

1. 和为K的子数组 (subarray_sum_equals_k)

2. 二维前缀和查询 (PrefixSum2D::query)

3. 差分数组更新 (DifferenceArray::range_add)

4. 异或前缀性质应用

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:空数组、单个元素、负数值

  3. 性能测试:10万数据量,1000×1000矩阵

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 数值范围处理

【学习建议】

  1. 理解核心公式:掌握前缀和、差分的核心公式

  2. 画图辅助:绘制前缀和、差分的变化过程

  3. 分类练习:按问题类型分组练习

  4. 模版化思维:记住通用框架,根据具体问题调整

【常见错误】

  1. 索引错误:0-indexed与1-indexed混淆

  2. 初始化错误:忘记初始化prefix[0]=0

  3. 边界处理:查询越界未检查

  4. 整数溢出:大数累加未使用long long

  5. 哈希表使用:错误使用count和find

【实用技巧】

  1. 调试输出:打印前缀和数组验证计算

  2. 小数据验证:手工计算小数据验证算法

  3. 对拍测试:与暴力解法对比结果

  4. 复杂度分析:确保算法在数据范围内可行

  5. 模块化设计:将前缀和、差分封装为类,便于复用


5.6 尺取法与双指针(课程18)

📦 核心代码模板

📊 双指针类型总结

类型特点适用场景例题
同向双指针两个指针同向移动,维护一个区间滑动窗口问题最短子数组和、无重复字符子串
相向双指针两个指针从两端向中间移动已排序数组的查找两数之和、三数之和
快慢指针一个快一个慢,速度不同链表问题、环检测链表中点、环形链表

📊 窗口收缩条件策略

问题类型窗口收缩时机目标
最小窗口满足条件时收缩找到满足条件的最短区间
最大窗口不满足条件时收缩找到满足条件的最长区间
统计数量每次右移都更新统计满足条件的区间总数

📊 常见问题模式与解法

模式关键点算法时间复杂度
最短/最长子数组维护窗口和,动态调整滑动窗口O(n)
包含所有字符哈希表统计频率,valid计数器滑动窗口O(n)
无重复字符字符位置记录,遇重复移动滑动窗口O(n)
已排序数组查找利用有序性,双指针搜索相向双指针O(n)
极值统计单调队列维护最大/最小值滑动窗口+单调队列O(n)
分治处理递归处理不满足条件的部分分治+双指针O(nlogn)

📊 关联题目索引

题目编号题目名称核心算法难度
LS1256两数之和(已排序)相向双指针
LS1257两数之差(已排序)同向双指针
LS1255k个最接近的数二分+双指针⭐⭐
P1638包含所有字符的最短子串滑动窗口+哈希表⭐⭐⭐
LS1259字符出现至少k次分治+双指针⭐⭐
LS1260求和游戏前缀和+双指针⭐⭐⭐
LS1254统计稳定子数组单调队列+双指针⭐⭐⭐
LS1258极差不超过k的分割数DP+双指针⭐⭐⭐

【各算法时间复杂度对比】

算法时间复杂度空间复杂度适用场景
最短子数组和O(n)O(1)连续子数组和问题
无重复字符子串O(n)O(字符集大小)字符串去重问题
最小覆盖子串O(n)O(字符集大小)包含所有字符问题
两数之和(排序)O(n)O(1)已排序数组查找
两数之差(排序)O(n)O(1)已排序数组差值查找
k个最接近的数O(logn + k)O(1)已排序数组查找
字符出现至少k次O(nlogn)O(n)分治字符串问题
统计稳定子数组O(n)O(n)极差限制问题
极差分割数O(n²)最坏O(n)分割方案统计

【核心算法详解】

1. 滑动窗口框架 (min_subarray_len)

2. 最小覆盖子串 (min_window_containing_all)

3. 单调队列维护极值 (count_stable_subarrays)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:空数组、单个元素、极值情况

  3. 性能测试:10万数据量测试

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 通用框架

3. 错误处理

【学习建议】

  1. 从简单到复杂:先掌握基本滑动窗口,再学复杂窗口维护

  2. 分类练习:按双指针类型分组练习

  3. 画图辅助:画出指针移动过程,理解收缩条件

  4. 模版化思维:记住通用框架,根据具体问题调整

【常见错误】

  1. 边界条件:数组越界、空指针

  2. 收缩条件:while还是if?满足条件还是不满足条件?

  3. 状态更新:先更新指针还是先更新状态?

  4. 初始值:DP数组、队列的初始化

【实用技巧】

  1. 调试输出:在循环中打印左右指针和关键状态

  2. 小数据测试:用手算验证小数据

  3. 对拍测试:与暴力解法对比结果

  4. 复杂度分析:确保算法在数据范围内可行


5.7 根号算法(课程19)

📦 核心代码模板

📊 根号算法类型总结

算法类型核心思想时间复杂度空间复杂度适用场景
分块数组数组分√n块,预处理块信息查询O(√n),更新O(1)O(n)区间查询+单点更新
莫队算法离线查询按块排序,移动指针O((n+q)√n)O(n)离线区间统计查询
根号分治高频/低频元素不同处理O(n√n)O(n)元素频率差异大
带修改莫队增加时间维度处理修改O(n^(5/3))O(n)带修改的离线查询

📊 块大小选择策略

问题类型推荐块大小复杂度分析说明
普通分块√nO(√n)查询,O(1)更新平衡查询和更新
莫队算法√nO((n+q)√n)平衡左右指针移动
带修改莫队n^(2/3)O(n^(5/3))平衡空间和时间维度
根号分治√nO(n√n)阈值设为√n

📊 莫队算法指针移动顺序

操作代码实现说明
扩展右边界while (cur_r < q.r) add(++cur_r);向右移动右指针
收缩右边界while (cur_r > q.r) remove(cur_r--);向左移动右指针
收缩左边界while (cur_l < q.l) remove(cur_l++);向右移动左指针
扩展左边界while (cur_l > q.l) add(--cur_l);向左移动左指针

📊 常见问题模式与解法

问题模式关键点推荐算法时间复杂度
区间和查询+单点更新不支持线段树时分块数组O(√n)查询
离线区间统计查询统计频率、相同对数等莫队算法O((n+q)√n)
判断区间是否有重复频率统计为0/1/2莫队或分块O((n+q)√n)
带修改的区间查询需要支持单点修改带修改莫队O(n^(5/3))
高频低频分类处理元素出现次数差异大根号分治O(n√n)

📊 关联题目索引

题目编号题目名称核心算法难度
LS1261数论分块基础分块思想⭐⭐
LS1262多维数论分块二维分块扩展⭐⭐⭐
P3901数列找不同莫队基础⭐⭐
P1494小Z的袜子莫队概率计算⭐⭐⭐
P2709小B的询问莫队维护平方和⭐⭐⭐
LS1263智力与模数根号分治应用⭐⭐⭐⭐

【核心算法详解】

1. 分块数组框架 (SqrtDecomposition)

2. 莫队算法框架 (MoAlgorithm)

3. 根号分治思想 (SqrtDecompositionByFrequency)

【测试用例设计】 代码包含多种测试用例:

  1. 基础测试:验证基本功能

  2. 边界测试:小数组、大查询、边界条件

  3. 性能测试:10万数据量,1万查询

  4. 交互测试:用户自定义输入

【扩展与优化】

1. 空间优化

2. 时间优化

3. 功能扩展

【学习建议】

  1. 理解分治思想:掌握将问题分解为√n规模子问题的思想

  2. 掌握模板:记住分块、莫队的通用模板

  3. 分析复杂度:理解为什么是O(√n)或O(n√n)复杂度

  4. 实践应用:从简单问题开始,逐步尝试复杂问题

【常见错误】

  1. 块大小计算:忘记+1导致块数量不足

  2. 边界处理:查询区间越界未检查

  3. 指针移动:莫队中add/remove顺序错误

  4. 离散化:忘记离散化导致内存过大

  5. 排序比较:莫队排序函数写错

【实用技巧】

  1. 调试输出:打印块信息、查询排序结果等

  2. 复杂度验证:通过大数据测试验证实际性能

  3. 对拍测试:与暴力解法对比结果

  4. 阈值调整:根据实际数据特征调整√n值

  5. 预处理优化:对高频信息进行额外预处理

 


📊 考核策略与时间分配

三小时考核时间分配表

时间段任务目标建议
0-10分钟审题规划了解所有题目快速浏览,标记难度
10-70分钟基础题攻坚完成3-4题优先做熟悉的题目
70-130分钟核心题突破完成2-3题仔细分析,避免失误
130-160分钟难题挑战尝试1-2题争取部分分数
160-180分钟检查调试确保正确性检查边界和格式

题目难度识别指南

数据特征可能算法时间预估策略
n ≤ 20暴力枚举/DFS15分钟状态压缩,注意剪枝
n ≤ 1000二维DP/Floyd20分钟注意空间复杂度
n ≤ 10^5贪心/双指针15分钟维护窗口状态
区间查询前缀和/BIT10分钟套用模板
最短路Dijkstra/SPFA20分钟注意负权判断
数学公式数论分块25分钟推导公式,注意边界

各模块时间分配建议

  1. 基础算法(30分):目标25-30分钟

    • 递归/搜索:5-10分钟

    • 排序/STL:5-10分钟

    • 简单DP:10-15分钟

  2. 核心算法(40分):目标50-60分钟

    • 动态规划:15-20分钟

    • 数据结构:10-15分钟

    • 图论算法:15-20分钟

    • 贪心/双指针:10-15分钟

  3. 高级算法(30分):目标30-40分钟

    • 数学/数论:15-20分钟

    • 贡献思维:10-15分钟

    • 综合应用:10-15分钟


🚨 常见错误与调试技巧

编译错误预防模板

运行时错误检查清单

测试用例设计

性能优化检查


🎖️ 考核评分标准解读

详细评分标准(100分制)

评分维度分值具体标准提分技巧
正确性40分通过所有测试用例充分测试边界情况
时间复杂度20分算法复杂度最优根据数据范围选择算法
代码规范15分结构清晰,命名规范,注释恰当函数模块化,命名规范
边界处理15分处理空输入、极值等特殊情况添加assert和条件检查
创新性10分优化或创新思路在注释中说明优化思想

各难度题目目标分数

题目类型分值范围目标分数策略
基础题20-30分28-30分必须全对,仔细检查
核心题30-40分32-38分争取大部分正确,部分优化
难题30-40分15-25分争取基础分数,尝试优化

总分目标分析

时间分配建议

题目难度建议时间检查时间总分目标
简单题15-20分钟5分钟满分
中等题25-30分钟5-10分钟80%+分数
难题30-40分钟10分钟50%+分数

📝 最后冲刺建议

考前一周复习计划

  1. 深呼吸法:遇到难题时,深呼吸3次,冷静思考

  2. 时间监控:每30分钟检查一次进度

  3. 先易后难:按顺序做题,遇到难题先标记,回头再做

  4. 检查清单:最后15分钟按清单逐项检查

  5. 积极暗示:告诉自己"我能行",保持自信

必备物品清单

考前注意事项

  1. 保证睡眠:考前保证7-8小时睡眠

  2. 合理饮食:考前不吃油腻食物

  3. 提前到场:提前30分钟到达考场

  4. 检查设备:确认电脑、编译器正常

  5. 保存备份:代码及时保存,防止意外


🏆 成功秘诀总结

五大成功要素

  1. 基础扎实:熟练掌握所有基础算法模板

    • 递归/搜索、DP、数据结构、图论

    • 模板代码信手拈来

  2. 思维灵活:能根据题目特征快速识别算法

    • 观察数据范围

    • 识别问题模式

    • 选择合适算法

  3. 代码熟练:模板代码熟练,减少调试时间

    • 常用STL操作

    • 算法模板熟练

    • 调试技巧掌握

  4. 心态稳定:遇到难题不慌,合理分配时间

    • 时间管理

    • 压力应对

    • 积极心态

  5. 检查细致:最后一定留时间检查边界和格式

    • 边界条件

    • 输入输出格式

    • 常见错误

🚨 考场时间管理黄金法则

30-30-30法则

5分钟原则

代码质量提升技巧

  1. 模块化编程:将功能分解为函数

  2. 清晰命名:变量名、函数名要有意义

  3. 适当注释:复杂逻辑添加注释

  4. 错误处理:考虑可能的错误情况

  5. 测试充分:多组数据验证

心态调整秘诀

  1. 接受不完美:不可能所有题目都完美解决

  2. 关注过程:享受解题过程,不只是结果

  3. 积极思考:每个错误都是学习机会

  4. 保持自信:相信自己的训练成果

  5. 放松心态:考试只是学习的一部分


🎉 最后寄语

亲爱的同学们

信息营选拔不仅考察算法知识,更考察你的学习能力、解决问题的能力和心理素质。这是一次展示自己的机会,也是一次成长的过程。

记住

相信自己的训练成果,保持冷静,仔细读题,你一定能在考核中展现出最好的自己!

预祝各位同学在乐知六中信息营选拔中取得优异成绩,开启信息学竞赛的精彩旅程! 🚀🌟

考核加油,未来可期! 💪🎉


📋 快速查阅索引

按算法类型查找
算法类型对应章节关键模板
递归/搜索一、1DFS、BFS、记忆化
动态规划背包、线性DP、股票
数据结构BIT、线段树、STL
图论算法Dijkstra、MST、并查集
数学数论五、1-3数论分块、筛法、快速幂
贡献思维五、4单调栈、贡献法
前缀优化五、5前缀和、差分
双指针五、6滑动窗口、相向指针
根号算法五、7分块、莫队
按课程编号查找
课程主要内容关键题目
01递归函数LS1028, LS1209
04网格BFSP1443, LS1217
10背包九讲LS1082-1088
12经典DPLS1016, LS1251
17状态设计LS1176-1179
07树状数组P3374, P1908
13区间统计LS1227, P1886
05图论最短路P4779, P4568
21生成树LS1276, P1396
15数论分块LS1261, P2261
14筛法LS1163, LS1164
16贡献思维LS1199, LS1244
20前缀优化LS1265, LS1264
18双指针LS1256, P1638
19根号算法P3901, P1494