1010 Sort
我们可以用调整法构造出唯一的贪心方案。
如果存在一种选择方案,那么将 b1 调整为 a1 中最小的元素,一定仍然合法;将 b2 选择 a2 中最小的、大于 b1 的元素,一定仍然合法,并且不会比原来的 b2 更大。
以此类推,我们可以构造出唯一的序列。
形式化地,对于任意一组 b1,b2,…,bn,我们可以定义序列 g1,g2,…,gn,满足:
- g1=min1≤j≤ma1j。
- gi=min{aij∣1≤j≤m,gi−1<aij},i≥2。
我们可以证明 ∀i,gi≤bi:
- 对 i=1,显然成立;
- 若 i−1 成立,则 i 时,既然 bi>bi−1≥gi−1,那么 bi>gi−1,于是 bi 也在 gi 的候选元素中,所以 gi≤bi。
因此只要存在一个解,那么贪心解就一定存在;反之,贪心解本身就是一个可行解。
此外,由于每一步都选择当前行中满足条件的最小元素,所以该序列是唯一确定的。
复杂度 O(nm)。
1007 Turn of a Page
如果存在一个 ai>S,那么包含这个元素的部分和一定大于 S,不可能等于 S。
如果存在一个 0<ai<S,那么无论如何排列,一定存在第一个满足条件的 ap;由于这样的元素前面只有 0 或 S,所以一定不存在 1≤q≤p,使得 ∑i=qpai=S。
所以现在可以将元素限制为 0 和 S 两种。如果 S 出现了,那么只要将序列排列成 S,S,…,S,0,0,…,0 即可;如果 S 没出现,自然不存在这样的重排。
复杂度 O(n)。
1008 谁输谁洗碗
直接暴力标记非法数字即可,复杂度 O(nk),其中 k=104,是可以过的。
其实本地造一个极限数据需要跑大概 10 秒,我个人认为如果是正式赛,这种题目应当适当放小数据范围。
1004 左右脑互搏
观察到 n 作为指数是可以接受的,所以可以对局面进行状压 DP。
具体地讲,对于 ∅ 状态,是输态;预处理出 Sl 表示 popcnt(x)=l 的所有 x,然后枚举 l=1∼n,所有 S∈Sl 都可以从 S∖{x}(x∈S) 并且满足异或和要求的集合转移过来,如果存在一个满足条件的集合是输态,那么当前就是赢态,否则是输态。
复杂度 O(n2n)。
1001 布布吃地瓜
我们先从简单的情况入手。
检查 0 是否能够成为答案,可以发现,如果存在一条不经过 0 的 (1,1)→(n,m) 的四连通路径,那么 0 是答案;
否则,如果存在每一条不经过 1 的 (1,1)→(n,m) 的四连通路径,那么 1 是答案;以此类推。
然后我们有一个 O((nm)2) 的做法:
- 从 x=0 开始枚举答案,每一次删掉所有 aij=x 的 (i,j),使用 BFS 检查 (1,1)→(n,m) 是否是四连通的。
考虑如何进行优化。设 Bx={(i,j)∣aij=x},那么 ∑x∣Bx∣=nm。
如果能够用上这个条件,即让复杂度为 O(∑x∣Bx∣)=O(nm),那么复杂度就是正确的。
这启示我们在每一轮循环只考虑 aij=x 的那些位置。
通过感性观察可以发现,下面这两件事是等价的,严谨证明需要依靠拓扑学知识,这里不做展开:
- 存在一条 (1,1)→(n,m) 的四连通路径,且路径上不经过任何 Bx 中的格子;
- 在 Bx 中,不存在一个八连通分量同时接触
我们可以用 BFS 判断,复杂度是 O(nm)。
1005 列车停放站
对于这种覆盖的问题,通常是需要通过贪心和考虑类似“第一个位置”这样的思路去做的。
对于每个询问 (x,y),考虑 i=argmaxj{lj∣rj≤y}。
如果 li<x 或者 argmax 的集合是空的,说明没有合法答案,答案就是 0。
否则答案至少是 1,那么假设最优解选择了 i1,i2,…,ik,由于最优解选择的区间都是合法的,那么有 rik≤y;根据 i 的定义,我们可以知道 li≥lik,于是调整 ik 为 i 后仍然是一个最优解。如果有多个满足条件的 i,那么对于每一个满足条件的 i,交换论证都成立,因此任选即可。虽然 i 不一定唯一,但是 li 一定是唯一的。
设 f(x,y) 是询问 (x,y) 的答案,那么 f(x,y)={0li<xor{j∣rj≤y}=∅1+f(x,li)otherwise。
于是我们可以离散化后预处理,然后对每一个询问倍增,这样复杂度是 O((n+m)logn)。
1006 游戏
其实这个题目并不是很难,但是看上去比较吓人,所以过的人不多。
重要的观察只是:如果某一个属性对最终答案能够产生贡献,那么它一定要 ≥40。
将每一个属性分开来看,设属性 i 最多能达到的值为 si,将 si 降序排序,由于 ∑si≤150,并且 si≥0,那么可以反证法证明 s4<40,即只有 s1,s2,s3 有可能产生贡献。
于是背包 DP 即可,复杂度 O(mk3)。
1009 GCD
对于每一个 i,令 gj=gcd(bj,bj+1,…,bi),根据 gcd 的结合律,有 gj=gcd(bj,gj+1)(j<i),又根据 gcd 性质有 gj≤gj+1。
当 gj<gj+1 时,这等价于 gjgj+1>1,又因为 gj∣gj+1,于是 gj≤21gj+1。又因为 gj≥1,所以从 gi=bi 开始,到 g1 为止,至多只有 O(logV) 个不同的值,其中 V=109,代表值域。
根据这个思想,我们可以对每一个 i 处理出一个 Li=min{j∣gj=bi},根据前面的单调性,这是可以二分的。
具体地说,我们二分一个 m,然后用 ST 表查询 m∼i 的 gcd 即可,那么这样的话复杂度是 O(nlognlogV);预处理 ST 表的复杂度也是 O(nlognlogV)。
对于每一个询问,我们可以先暴力的找出这 O(logn) 个区间,然后对于每一个区间 [L,R] 来说,我们有这样的一个贪心的调整论证法:如果最优解存在一个不在 L 处的操作,我们可以把它取消掉,并且让这个操作在 L 处进行,那么操作仍然是合法的。根据这样的思路,每一段的操作都可以在区间的左端点处进行。
对于第一个区间 [L1,R1],容易看出 L1 处的操作数 t1≥⌈gL1maxL1≤j≤R1aj⌉。
如果 t1>⌈gL1maxL1≤j≤R1aj⌉,我们可以把多出来的操作都放到 L2 处,由于 gL2>gL1,所以操作仍然合法,那么我们就可以断定 t1=⌈gL1maxL1≤j≤R1aj⌉。
对于后续的段,我们可以记录一下前面累积减去了多少,然后最大值用 ST 表查,于是单次询问复杂度 O(logn)。
这样的话总复杂度为 O(nlognlogV+qlogn)。
1002 1003 通行证
把二进制数看成集合,设询问的集合是 Q,那么对于每一个位置 (i,j),它的答案为 k 的充要条件是,在这个十字框中,所有距离 ≤k−1 的 (i,j) 都满足 aij⊆Q;距离 =k 的 (i,j) 中存在一个 aij⊆Q。
简单讨论可以发现这这等价于 ⋃dij≤k−1aij⊆Q 并且 ⋃dij≤kaij⊆Q。
反过来看,设 Sk−1=⋃dij≤k−1aij,Sk=⋃dij≤kaij,那么对于所有满足 Sk−1⊆Q 并且 Sk⊆Q 的询问 Q,答案都会被 +k。
这里特殊之处在于 Sk−1⊆Sk,那么根据 SOS DP 的方法,我们可以给 dp(Sk−1)←dp(Sk−1)+k,并且 dp(Sk)←dp(Sk)−k。
那么朴素预处理加上一个 SOS DP 就可以做到 O(n3+VlogV) 预处理,其中 V=215 代表值域。
对于询问,我们发现在 ≥215 的二进制位都是没有用的,所以我们可以给每一个询问取前 15 个二进制位,直接 O(1) 回答。
进一步地,我们可以发现,当 Sk−1=Sk 的 k 的数量很少,至多只有 15 个。
我们可以 O(logV) 枚举每一个位,然后 O(n2) 对每个 (i,j) 处理出来上下左右四个方向的第 k 位发生变化并且距离最近的那个位置。
这样的话复杂度就变成了 O(n2logV+VlogV) 预处理,O(q) 处理询问。
实现上来说,我们给每一个位置都加入一个边界当作变化的位置 min(i+1,j+1,n−i+2,n−j+2),当遍历到这里的时候就不再给 DP 数组减。