#40 懒得写了,#41 题目质量过低。
A
有 \(n\) 张长度为 \(m\) 的纸条,每张纸条有 \(k_i\) 个位置有小写字母,其他位置透明。你需要合理从上到下排列这些纸条,使得最终在上方看到的字符串为 \(s\),保证对于每个位置,至少一张纸条在该位置有一个字母。给出方案或无解。
\(1\le n,m\le 10^5, \ \sum k_i \le 2\times 10^5\)
纸条用的越多越好,这是一个类拓扑排序。提取出每张纸条被限制的位置,每放上一张纸条就把所覆盖的位置全标记一下,解放这些位置。对于每张纸条,记录一个 \(cnt_i\) 表示剩余仍被限制住的位置数,把 \(cnt_i = 0\) 的纸条加入队列。
B
给定两个序列 \(a_{1\dots n}, \ b_{1\dots m}\)。你需要分别选择 \(a\) 和 \(b\) 中一段,满足选出的两段长度相等,并且两个子段对应位置上的数相加后是一个回文序列。求最长的回文序列。
\(1\le n, m \le 10^5\)
设提取出来的子段为 \(A,B\),那么 \(A+B = (A+B) ^ R \Rightarrow A - A^R = B^R - B\)。处理出 \(a,b\) 两个序列以及 reverse 后的序列的哈希值即可 \(\mathcal O(1)\) 判断。
回文序列有奇偶两种,对于奇偶两种都做一次二分,转化为判定 \(mid\) 是否合法。
提取出 \(a,b\) 的所有长度为 \(mid\) 的子段,扔进哈希表里判断一下是否有相同的即可。
- 启示:每一步思路清晰。
C
一个长度为 \(n\) 的排列,有若干个位置未填写。你需要填写这些位置,求出最大的 LIS。
\(1\le n\le 10^5\)
设 \(p_i\) 为前 \(i\) 个位置中未填写的位置个数,\(q_i\) 为 \(1...a_i\) 中未出现的数字个数,那么 \(f_i = \max\limits_{j = 1} ^ {i - 1} \{f_j + \min(p_i - p_j, q_i - q_j)\}\),cdq 分治即可。
D
一个值域为 \([1, n]\) 的整数序列 \(a_{1\dots n}\),满足每种整数最多出现 \(2\) 次。设 \(S[l, r]\) 为 \(a_{l\dots r}\) 组成的可重集,设 \(T\) 为所有 \(S[l, r]\) 组成的集合,求 \(\text{card}(T)\)。
若一个区间 \([l, r]\),存在另一个区间 \([l', r']\) 满足 \(l' < l\) 且 \(S[l, r] = S[l', r']\),那么不合法,考虑用 \(\frac {n(n + 1)}2\) 减去所有不合法的区间。
一个区间 \([l, r]\) 不合法,当且仅当满足以下之一:
-
存在 \([l', r']\) 满足 \(r' < l\) 且 \(S[l', r'] = S[l, r]\)。
-
存在 \(l\le l'\le r\),满足 \(S[l', r] = S[l - (r - l' + 1), l - 1]\)。
设 \(b_i\) 为前一个等于 \(a_i\) 的 \(a_j\) 的位置 \(j\)。若不存在,则 \(b_i = -2i\),设 \(c_i = \max(0, b_i)\)。
条件一很好算,令 \([b_i, c_i]\) 为区间,考虑单调栈 + 线段树维护最小值个数。
条件二可以枚举 \(l'\),维护 \(r\) 的信息。设 \([l', r]\) 这一段的 \(c_i\) 的最大值为 \(p_r\),那么区间 \([l = p_r, r]\) 有贡献。一个区间可能贡献多次,我们强制令每个 \(r\) 通过最大的 \(l'\) 来贡献。具体的,在每个 \(r\) 上维护一个标记。\(r\) 位置上统计的最小值为 \(0\) 且有标记,去除标记并对答案造成贡献。当 \(p_r\) 改变时,对应贡献到的区间会改变,所以应重新给这些 \(r\) 打上标记。
我们需要动态求出所有最小值的位置上的标记,去除所有最小值位置上的标记,或者给一段位置重新打上标记,这些都可以用线段树解决。
减去同时满足条件一和条件二的情况,这种情况只可能是 \(l' = l\)。考虑求出满足 \(p_r = l' - 1\) 的 \(r\) 的区间 \([r_0, r_1]\),贡献为这一段区间中最小值为 \(0\) 的位置的标记个数。
启示:更换枚举对象(枚举 \(l'\));最小表示法;容斥拆条件
标签:le,标记,纸条,42,序列,位置,区间,CSP,模拟 From: https://www.cnblogs.com/Sktn0089/p/18493646