省冲笔记
作者:互联网
暴力枚举 前缀和
例1
十次函数 $f(x) = \sum{10}_{i=1}a_ixi+a_0$,已知 $f(1), f(2),f(3),\dots,,f(11)$,求 $f(12)$
疯狂求导
例2
读入 $n$ 个数字,有一个数字出现次数大于一半,剩下的数字随机出现,求出现次数最多的数字。(空间限制 $100$ 的数组)
-
法一
统计每一位上 $0~9$ 出现的次数
-
法二
每次抵消掉两个不相等的数,剩下的那个数
例3
题面同例2,大于一半改为大于 $k/n$
- 每次抵消 $k$ 个数,统计没有被消除掉的数字的历史出现次数
例4
$2n+2$ 个数字,其中有两个数字是单独出现的,剩下的数字出现次数都为偶数,分别求那两个数字
- 异或之后的结果是两个数的异或值,这两个数必定有一位上互不相同,令 $f[i]$ 表示二进制表示第 $i$ 位上是 $1$ 的所有数的异或值
分割线以下是难题
例1
$n\times m$ 的灯泡矩阵,每次改变一个位置的状态会影响上下左右的状态,给定初始状态问能不能全灭
- 一个位置上下左右包括他自己最终操作次数和模 $2$ 的结果是定的 ---> 列 $nm$ 个线性方程(时间复杂度起飞)
- 枚举第一行的开关方法,一路求到最后一行看最后一行能不能全灭 ($O(2^n\cdot nm)$)
- 设 $a_{i,j}$ 表示某一位置需要的操作数,$c_{i,j}$ 表示某一位置的状态,则 $$c_{i,j} + a_{i-1,j} + a_{i,j+1} + a_{i,j-1} + a_{i + 1,j} \equiv 0 \pmod2$$,从第一行开始将下一行的 $a$ 表示一下, 一直到最后一行判断是否合法即可
例2
$n\times m$ 的灯泡矩阵,每次可以选择一列或一行将灯泡反向,给定初始状态,问操作恰好 $k$ 次最多能让多少列灯泡全为 $1$
- 暴力枚举某一列是否亮着以及这一列按了没有,行的状态就确定了,时间复杂度 $O(2nm^2)$
- 有一性质:对于任意两列而言,当且仅当他们初始状态相同或互补,则他们可以同时变亮,将初始的列分类即可
例3
$n\times m$ 的矩阵,每个位置都有 $a_{i,j}$ 个地鼠,有一个 $r \times c$ 的锤子($r, c$ 任意),每次可以将这么大的范围内地鼠全部减一(必须保证这一些格子里至少有一个),至少用多少次打完?
- 暴力枚举 $r, c$ ,
思考题
暴力枚举 双指针
例1
给定长度为 $n$ 的数组,求有多少个区间 $[l,r]$ 满足 $\sum \limits_{i=l}^ra_i ≤ k$。
- 双指针直接枚举,注意 $r$ 过不了 $l$ 的情况
例2
$n$ 张 $m$ 种卡片,只能买连续的,求最少需要多少钱集齐 $m$ 种。
- 双指针直接扫
例3
给定长度为 $n$ 且只含 $\texttt{R G B}$ 的字符串,求要获取长度为 $k$ 且形式为 $\texttt{RGBRGB}\dots$ 的字符串最少需要修改多少个字符。
- 统计每个长度为 $k$ 的串,按除以 $3$ 的余数分类统计即可
例4
给定长度为 $n$ 的数组,求有多少个区间异或和等于他们的和。
- 性质:$A \oplus B ≤a+b$,所以当且仅当区间做与等于 $0$,满足题意,直接双指针扫
例5
给定长度为 $n$ 的数组 $A,B$,求 $\sum\limitsn_{i=1}\sum\limitsn_{j=1}(A_i+B_j)$ 的异或和。$n≤2\times10^5, 0 ≤A_i,B_i<2^{28}$
- 当 $A_i+B_j$ 第 $28$ 位 为 $1$,当且仅当 $A_i+B_j\in[2{28},2{29}-1]$,即 $B_j\in[2{28}-A_i,2{29}-1-A_i]$,对 $B$ 排序后二分即可。对于 $27$ 位,对每个数对 $2^{28}$ 取模,剩下的依次操作即可。
例6
- 考虑子任务 $1$: 对于任意一行 $sum >2k$,直接双指针扫;对于任意一行 $su m \in [k,2k]$,直接输出;
例7(环形序列)
有一个环形序列,$A$ 可以指定一个位置将环拆开,接下来和 $B$ 轮流玩游戏,$A$ 先手。$A$ 可以任意取走一个元素,$B$ 只能从最左边拿,求 $A$ 能得到的最大分数以及拆的位置。
- 考虑链的情况,将前 $\frac{n}{2}$ 个元素记为 $1$,后 $\frac{n}{2}$ 个元素记为 $-1$,满足题意的前缀和一定属于 $(-∞,1)$,直接将输入前缀和,找出最后大于等于 $2$ 的位置,将其后作为链的开始,一定满足题意。
- 考虑上述前缀和的情况,如果将前 $n$ 个移到后面,也就是后面的前缀和要减去前面的前缀和,即是区间修改区间最大值的题,线段树即可
贪心算法
经典模型:偏序关系
例1
给定 $n$ 个正整数,求其首尾相连能连成的最大整数
- 当成字符串处理,对于结果中任意两个相邻的数字元素,满足 $\texttt{A}+\texttt{B}>\texttt{B}+\texttt{A}$,即为最优解
例2 P1080 [NOIP2012 提高组] 国王游戏
- 贪心策略:左手右手乘积小的在前。证明:考虑相邻的两个大臣 $i,j$ ,且 $i$ 前面所有左手的乘积为 $S$,则采用此策略 $\max(\frac{S}{r_i},\frac{S\cdot l_i}{r_j})$,不采用此策略 $\max(\frac{S}{r_j},\frac{S\cdot l_j}{r_i})$,又因为
经典模型:线段覆盖
例1 P1803 凌乱的yyy / 线段覆盖
- 截止越早,影响越小
例2
给定 $n$ 个线段,求最多有多少个线段有交集。
经典模型:按位贪心
例1
给定数组 $a$,$q$ 组询问给出 $k$,求 $k \oplus a_i$ 最大值。
- 给 $a$ 做 01-Trie,贪心即可。
例2
给定一个由 |, ^, &
组成的算式,如 m | 124 ^ 235 & 12423 ^ 12312
,给定 $k$,求 $m$ 取何值且 $m \in [0,k]$,式子的结果最大。
思考题
$n$ 个数字,$1 ≤a_i≤10^{8}$,设 $S(i,j)$ 表示十进制下 $a_i+a_j$ 进位次数,求 $\sum\limitsn_{i=1}\sum\limitsn_{j=1}S(i,j)$。
- 对任意一个数字,个位有没有数字进位显然可以 $O(n)$ 处理,十位有没有数字进位可以直接将其看作两位数处理,问题转化为每个数字的每后 $i$ 位大于等于特定 $k$ 的有多少个数,排序后对每位二分即可
例1(随机数生成器)
$n\times m$ 的矩阵中有 $[1,n\times m] $ 中的每个数,左上角走到右下角,经过 $n+m-1$ 个数,排序后将其视作字符串的 $\texttt{ASCII}$ 码,求给定矩阵后生成的所有字符串的字典序最小的字符串。
- 一定将较小值包含在路径里更优,先求能走到 $1$,能经过的路径组成的矩阵,再求能走到 $2$,能经过的路径组成的矩阵,取交集后递归。具体实现可以维护每一行可以经过的区间。
例2
俯视一个蓄水池,$n\times m$ 的矩阵中有每个点的高度,水会向四周流,求要使水不溢出边界,最多能蓄多少水。
- 定义某一条路径上最高点为这条路径的长度,则这个点的最大蓄水值为所有这个点逃出边界的路径的最小值,转化为最短路问题,再设一个虚点为边界的集合,问题转化为这个虚点到内部每个点的“最短路” 的和
例3
有 $n$ 个矮人和 $n$ 个精灵,每个矮人、精灵都有一个能力值,能力值两两不相同,矮人排成一个 $1$ ~ $n$ 的环,第 $i$ 个精灵会从第 $a_i$ 个矮人开始挑选第一个无对手的矮人比赛,如何安排精灵出场顺序使胜利场数最多。
- 先考虑链的情况,若任意位置后缀和小于等于下标,则成为了链的情况,问题转化为区间田忌赛马。
- 环形情况证明同 [此题](# 例7(环形序列))
例4
有 $n$ 个形如 $\texttt{15}$ $\texttt{15}$ $\texttt{15}$ $\texttt{14}$ 的字符串,将 $\texttt{*}$ 替换成数字并使 $n$ 个数单调递增,并使最后的结果数字尽量小,输出方案。
task 1: $len ≤6$ task 2: $len ≤18$ task 3: $len < 100$
- Task 1: 枚举 $1$ 至 $10^6$ 的数字
- task 2: 将星号组成数字开始二分
- task 3: 从高位贪心
二分
模板
int now = 0;
for(int stp = len; stp >= 1; stp >>= 1) {
if(now + stp <= len && check(now + stp)) now += stp;
}
// 倍增
例1
四个长度均为 $n$ 的数组 $A,B,C,D$,任意 $a, b, c, d$ 求多少种方案使 $A_a+B_b+C_c+D_d = 0$
- 转化为 $A_a+B_b=-(C_c+D_d)$,暴力成两个数组排序双指针即可
例2
$n$ 件衣服需要晾干,含水量为 $a_i$,每分钟蒸发掉 $1$ 单位水,一个吹风机每分钟可以蒸发 $k$ 个单位水,求最小时间
- 二分总时间,晾干的不管,没晾干的统计需要吹多少分钟,总时间再和二分的总时间比
例3
$n$ 个项目组,每个项目组有 $a_i$ 个人,每次要从不同的 $k$ 个项目组里抽一个人,问最多能取多少次
- 二分次数 $t$,若 $\sum\limits^n_{i=1}\min(a_i,t) ≤tk$,则可以,
例4
无限长数轴,有一个机器人一开始在 $0$,有一连串指令形如 $\texttt{LRRLRLLRLRLRRLRLLR}$,希望最终停在一个之前没有走过的地方,但是可以放墙,若下一步撞墙则不会走,最少需要几堵墙?方案数?
思考题
有一个动物园,动物都被关在左上角格子,逃出动物园必须从右下角逃出,上下左右均有边界,有两种动物老虎 $T$ 和牛 $C$,走过的路径会留下自己的脚印,后面的会覆盖前面的脚印,给定矩阵最后状态,求最少逃出去了几只动物。
例5
字符串,形如 $\texttt{.Y..YYY.YY..}$,最多可以交换相邻两个字符 $k$ 次,最后最多能得到多少个连续的 $\texttt{Y}$
- 二分答案。
例6
有一堵墙,堆沙袋最左边位置高度不能超过 $H$,向右堆和左边一堆相差不能超过 $1$,要求到最右边得堆个 $1$,要恰好用完 $n$ 个沙袋,问最少堆多少列。
- 只和最高点有关,二分。
搜索
例1
见题解