A/B
较为简单,略去。
C
预处理一下,然后前缀和就好了。
时间复杂度 \(O(n)\)。
D
用链表来记录字符串。
注意到每次能够消去意味着链表上连续三个节点拼起来是 ABC
,然后从左到右一个个算就行了。
匹配到的话把三个节点一起删掉。
时间复杂度 \(O(n)\)。
E
注意到 \(N\le 8, M\le 28\),树边为 \(N-1\le 7\) 条
所以直接 dfs,计算次数不超过 \(C_{28}^7=1184040\) 次。
F
发现两个变量之间的关系是确定的,启发我们使用带权并查集,然后每次尝试合并,如果可以就加入到集合里面。
具体的,如果 \(x\xrightarrow{+w} y,x\xrightarrow{+d_x}r_x,y\xrightarrow{+d_y}r_y\),那么 \(r_x\xrightarrow{w+d_y-d_x}r_y\)。
G
乍一看 \(N\le 22\),以为只能 \(O(2^N)\),但是仔细一想,发现并不一定。
先稍微分析一下,显然有:
Split A...
操作一次性全部做完就行了。因为先后操作没有关系。Choose ...
操作,对于每一个 \(a_i\) 只要做一遍就行了。
所以相当于把 \(a\) 分成 \(i\) 段,每段和 \(b\) 中的某个连续段配对。
于是先想到 \(f_i\) 表示 \(a\) 的前 \(popcount(i)\) 个数和 \(b\) 中 \(i\) 二进制下为 1
的每一位 \(j\) 对应的 \(b_j\) 配对(例:\(5=(101)_2,j=\{0,2\}\))。
然后考虑枚举这一连续段的长度。
所以有 \(f_i=\min_{j\subsetneq i}f_j+c\),并且 \(j\) 还需要满足 \(j\text{ xor }i\) 的二进制表示下的 1
是连续的。
为了方便实现,可以枚举 1
连续段的长度和 \(b\) 中的起始位置。
后记:第一次 AK,激动。