CF1383E Strange Operation
Question.1
容易猜到是根据答案序列的某种性质进行计数,那有什么性质?
ANSWER
考虑将答案视作一段一段的连续块,那我们发现:
- 操作 00/10/01 就相当于将一个 0 的连续块长度减一。如果这个连续块长度为 0,就将两边的连续块合并。
- 操作 11 相当于将一个 1 的连续块长度减一(前提是操作前长度大于 1)
但这里的合并操作(将两个连续块合并)使得这个看起来很复杂。考虑换一种刻画方式,我们设最终的序列
a 表示相邻两个
1 之间的
0 的个数。
举个例子
对于一个串
00101100010,最终的序列
a={2,1,0,3,1}。
对于一个串
101101,最终的序列
a={0,1,0,1,0}(两边的就算没有
0 也要记录)
那么我们现在再来考虑两个操作:
- 操作 00/10/01 就相当于将一个 ai>0 的 ai 减一。
- 操作 11 相当于将一个不在首尾的 ai=0 删掉,把两个相邻的 1 变成一个 1。
我么先计算开始和结束的那两个
a1,ak,这个的贡献是
(a1+1)(ak+1)。
假设初始为
a,因此,最终生成的
b 序列要满足,存在一个
a 的子序列
a′,使得
bi≤ai′
Question.2
我们需要加条件,使得我们可以通过
a 的子序列来不重不漏的算出
b 的方案数。
ANSWER
考虑一个贪心算法,假设我们当前要对于一个
b,找到对应的
a 子序列。
我们直接从左往右扫
a,如果当前
ai≥bj,那就将
i 和
j 匹配,且
j 加一。
这样,我们可以保证每个
b 序列都是对应着一种情况。现在,我们对于每个
a 的子序列计数即可。
Question.3
是否存在多项式复杂度的计数方法?
ANSWER
考虑 DP,设
fi 为匹配到
ai 时,
b 的方案数。考虑
fj→fi 会发生什么。
设与
ai 匹配的
b 值为
x。根据
Question.2 中的贪心方法,
t=j+1maxi−1at<x≤ai。
因此,
fi=j=0∑i−1fj×max(0,ai−t=j+1maxi−1at)。复杂度为
O(n2)。
注意
j=i−1 时,由于没有
max 的限制,
fj×(ai+1)。
Question.4
能否对这个 DP 进行优化?
ANSWER
观察这个 DP 式子,显然只有
ai>maxt=j+1i−1at 时才有贡献。
考虑单调栈,我们在加入
ai 到单调栈的时候,弹出的
aj 都满足
aj 小于
ai 的条件。因此,对于单调栈内的每个元素,维护以该元素为最大值的
fi 总和。
转移是普通的,时间复杂度
O(n)。
CF1383F Special Edges
Question.1
我们能否不考虑特殊边的边权去跑最大流?
ANSWER
首先可以把最大流转化成最小割。
如果我们想不考虑特殊边的边权,那我们可以考虑直接枚举这些边在最小割中是否选择。
Question.2
现在,我们只需要考虑如何对于网络流,固定某条边是否选 / 不选即可。但我们要让边权尽量小,否则网络流无法通过。
ANSWER
首先,一种很显然的方法是将必选的边视为
0,不选的是
+∞,但是这样边权过大。
我们考虑将不选的边权视为
25,这样虽然这条边有可能在最小割里,但是这时这条边的代价是
25,还不如本来就选这条边,代价是
wi≤25。时间复杂度为
O(2k×flow(n,m)+q×2k),无法通过。
Question.3
如何优化?
ANSWER
注意到边权很小,所以我们考虑使用 FF 算法(一种基于流量的网络流算法)。
我们考虑先对不选边的情况跑一遍网络流,求出剩下来的残余网络。然后,我们要找到一个枚举二进制数的顺序,使得每次改变的量尽量小。
考虑格雷码,相邻两个格雷码只会差一个二进制位。因此,就有
0→1 和
1→0 两种情况。
- 0→1,即加边:我们直接在这条边上加入 25 的流量即可。
- 1→0,即删边:考虑强制退流,我们记录这条边原本的流量 f,然后将 1→u, v→n 两条路径全部删除 f 的流量即可。
CF1268D Invertation in Tournament
不会,回家补,先记几个结论。
Lemma.1
当
n≤7 时,反转的点至多一个。
Lemma.2
当
n=4 时,答案为
−1,当
n=6 时,答案为
2 和
18。