S[i, j] = 第i行j列格子左上部分所有元素的和
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
2.1 链表与邻接表:树与图的存储
2.2栈与队列:单调队列、单调栈
常见模型:找出每个数左边离它最近的比它大/小的数
常见模型:找出滑动窗口中的最大值/最小值
求模式串的Next数组:
(3)维护到祖宗节点距离的并查集:
核心思想:将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低
小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果
vector, 变长数组,倍增的思想
支持比较运算,按字典序
支持比较运算,以first为第一关键字,以second为第二关键字(字典序)
substr(起始下标,(子串长度)) 返回子串
c_str() 返回字符串所在字符数组的起始地址
push() 向队尾插入一个元素
push() 向栈顶插入一个元素
count() 返回某一个数的个数
(2) 输入一个迭代器,删除这个迭代器
和上面类似,增删改查的时间复杂度是 O(1)
any() 判断是否至少有一个1
3.2 树与图的遍历:拓扑排序
树是一种特殊的图,与图的存储方式相同。
因此我们可以只考虑有向图的存储。
时间复杂度O(n+m), n 表示点数,m 表示边数
时间复杂度 O(n+m), n 表示点数,m 表示边数
时间复杂度 O(nm), n 表示点数,m 表示边数
时间复杂度 平均情况下O(m),最坏情况下 O(nm), n 表示点数,m 表示边数
spfa判断图中是否存在负环
时间复杂度是 O(nm), n 表示点数,m 表示边数
时间复杂度是 O(n2+m), n 表示点数,m 表示边数
3.5 二分图:染色法、匈牙利算法
时间复杂度是 O(n+m), n 表示点数,m 表示边数
时间复杂度是 O(nm), n 表示点数,m 表示边数
此章节见算法题高课!!!
给定 N 个闭区间 [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。
输出一个整数,表示所需的点的最小数量。
1.将所有区间按照右端点排序
2.遍历所有区间,ed初始化为无穷小
如果本次区间不能覆盖上次区间的右端点,ed<e[i].l,那么需要选择一个新的点res++;ed=e[i].r
如果本次区间可以覆盖上次区间的右端点,则进行下一轮循环
给定 N 个闭区间 [ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。
输出一个整数,表示最小组数。
有若干个活动,第i个活动开始时间和结束时间是[SiSi,fifi],同一个教室安排的活动之间不能交叠,求要安排所有活动,少需要几个教室?
1.将所有区间按照左端点从小到大排序
2.用小根堆维护每一个不相交区间的右端点的最大值
3.若区间之间有交集,那么增加一个新的教室
给定 N 个闭区间 [ai,bi] 以及一个线段区间 [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出 ?1。
第一行包含两个整数 s 和 t,表示给定线段区间的两个端点。
第二行包含整数 N,表示给定区间数。
接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。
输出一个整数,表示所需最少区间数。
如果无解,则输出 ?1。
1.根据所有区间的左端点从小到大排序
2.从前往后枚举每个区间,在所有能覆盖st的区间里,选择右端点最大的区间,然后将st更新为右端点的最大值
6.4 最大不相交区间数量
给定 N 个闭区间 [ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。
输出可选取区间的最大数量。
第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。
输出一个整数,表示可选取区间的最大数量。
1.根据所有区间的右端点从小到大排序
2.从前往后枚举每个区间,如果当前区间已经包含点,则pass,否则,选择当前区间的右端点
3.ps:该题实质上是区间选点的本质
参考:acwing算法基础模板