D1T1:
严格众数有一种处理方法就是摩尔投票法:既然这个众数 \(x\) 出现了超过 \(\dfrac n 2\) 次,那么我们每次把一个非众数 \(y\) 和 \(x\) 消掉,即使是在最劣情况下,最后一定能剩下 \(x\)。 而这种信息是可合并的。
维护一个二元组 \((val, cnt)\) 表示对于每个值 \(val\),其出现次数为 \(cnt\), 合并时若两个 \(val\) 相等,\(cnt\) 累加,否则就用小的出现次数消掉大的出现次数。
考虑末尾添加和删除操作,合并操作,一个直接的想法是 deque 启发式合并,容易炸空间。更好的实现是双向链表。合并就直接线段树合并即可。 注意最后如果有值不一定是严格众数,还需要检验每个集合中其出现次数。
D1T2:
先考虑 \(l_i = r_i, k = 0\) 的部分,相当于询问一个局面是否能胜利。
考虑 dp:设 \(dp_{i, j, k}\) 表示考虑到前 \(i\) 个数,目前钦定延伸到 \(i\) 的区间有 \(j\) 个,延伸到 \(i+1\) 的区间有 \(k\) 个。转移考虑枚举从 \(i\) 开始的操作二,设有 \(x\) 个,那么覆盖 \(i\) 的总共就有 \(j+k+x\) 个,在从 \(j\) 个钦定到 \(i\) 的位置中选择 \(y\) 个钦定到 \(i+1\) ,转移到 \(dp_{i+1, k+y, x}\)。 直接转移太慢,先找一些性质吧:
- 若操作 2 区间长度 \(\geq 6\) 的话,我们总能拆成若干个小区间,长度不超过 \(5\), 也就是说我们只用 \(3, 4, 5\) 的长度即可,缩减了决策量。因此 \(j \leq 6, k \leq 3\)。
- 若存在两个相同的操作二,显然可以拆成若干个操作 1,且若从一个位置 \(i\) 开始存在 3 个,显然可以换成一个操作 1 和两个下一个位置开始的操作 2。
因此我们得到:\(j \leq 4, k \leq 2\) 。实际上,我们有更强的结论:\(j \leq 2, k \leq 2\),因为当延伸到 \(i\) 的位置 \(\geq 3\) 个时都可以拆分成若干个操作 1 和不超过 2 次操作 2。在考场上可以不断缩小 dp 某一维度然后对拍得到。
状态已经足够简单,时间复杂度 \(O(n)\)。
当 \(l = r, k \neq 0\) 时,我们设 \(dp_{i, j, k, l}\) 表示在 dp 的基础上,已经用了 \(l\) 个石子是否合法,同样 dp 即可。
但我们手玩几个例子可以发现,在绝大数情况下,若放 \(k\) 个石子合法,则 \(k+1\) 个石子合法。
- 若原先存在操作 2 且长度不为 3, 显然将一个端点放一个石子后操作 2,然后再做操作 1。
- 若原先存在操作 1, 直接放入这个位置。
因此,不合法情况一定没有一次操作一且操作二长度为 \(3\)。 容易发现不满足条件的只有两种情况:
- \(n = 3 \and k = 1\), \(a_1 =a_2=a_3 = 1\)。
- \(k = 0, \forall i, a_i = 0\)。
特判即可。
否则设 \(dp_{i, j, k}\) 表示在这个状态下需要最少添加石子的个数,无法满足则为 \(k+1\)。 同样 dp 即可。
当 \(a\) 不固定时,由于 \(j, k \leq 2\), 我们枚举 \(a\) 只用枚举到 \(4\) 即可。 由于我们在最外层还要计数 dp 方案,不难想到 dp 套 dp:设 \(g_{i, S}\) 表示考虑到前 \(i\) 个位置,当前 \(f_{i}\) 的状态为 \(S\) 的方案(对于 \(j = 0, 1, 2; k = 0, 1, 2\) 都要记录一个 dp 值,\(k\) 的值为 100), 一眼看过去 \(S\) 是 \(101^9\) 级别的,但我们搜一下合法状态,当 \(j \leq 3, k \leq 3\) 时,只有不到 7000 个合法状态!于是先预处理对应的转移然后 dp,时间复杂度 \(O(n \times 7000 \times 4)\),
D1T3:
会了我还在这个地方???
D2T1:
【提示】
数据没有针对任何合理的哈希算法做任何针对性的构造,所以在合理范围内不需要过度担心因为哈希碰撞而产生的失分问题。
由于题目明示哈希,于是考虑树哈希。
先将一种不那么容易被卡的 hash 方法:设计一个 hash 函数:为一个低次多项式,然后把输入的值随机扰动。更具体的,设 \(hash_x\) 为 \(x\) 子树的 hash 值,则有 \(hash_x = 1+\sum f(hash_y)\), 优点是可以换根。
设计函数 \(match(x, y, cnt)\) 表示第一棵树的 \(x\) 和第二棵树的 \(y\) 能否在 \(cnt\) 次删除后同构,先预处理出两棵树的子树哈希值,对于能匹配的 \(x\) 和 \(y\) 的子树就让他们匹配。否则假设剩下 \(c\) 个子树没有匹配,显然 \(c \leq 5\),预处理 \(f_{x,y}\) 表示 \(x\) 和 \(y\) 能否匹配,然后就是一个二分图完美匹配问题。可以用网络流解决。
当然由于 \(c \leq 5\),那么我们全排列枚举 \(i\) 的匹配也行。
时间复杂度不会证,反正跑的飞快。
D2T2:
由于逆序对数量不好直接用 dp 来表示,考虑贪心。
通过观察,容易得到所有 \(a_i\) 的取值都应该是给定的 \(l_i, r_i, v_i\) 的其中一个,如果不是的话显然可以通过调整实现,而且逆序对个数不会增加。
一个部分一个部分考虑:
-
当 \(l = r\), 也就是确定了某些位置的值后,我们所填的 \(a_i\) 一定满足他们两两不构成逆序对,因为若存在 \(i < j, a_i >a_j\) 显然交换 \(a_i, a_j\) 更优。 此时局部最优解构成了全局最优解。
考虑从右往左贪心,先把有值的 \([1,a_i)\) 区间加 1, 用一个线段树实时维护当前的最优选择。具体来说,线段树的每个下标记录了若当前位置选择 \(v\) 会产生的逆序对,每次贪心选择最小的即可,并把 \([a_i+1,m]\) 区间加 1。这样决策,相当于一个前缀减和后缀加,若某一时刻 \(i < j \and c_i \leq c_j\), 则此后显然也有 \(c_i \leq c_j\) ,于是贪心是正确的。
-
当区间两两不交时,我们希望区间内部没有逆序对产生,于是我们想区间 \(\min\) 就放在最前面,然后就执行第一个操作即可。感性理解一下,发现这很对。
正解考虑把两个部分拼起来考虑:我们还是对每一个区间按限制排序后,线段树区间覆盖得到每个区间 \(\geq k\),若一个区间不存在一个 \(a_i = k\) 显然无解。
对于每一个值 \(v\), 我们记录 \(beg_v\) 表示这个值最少要在 \(beg_v\) 后出现,先填上每个数的下界,把每个区间的左端点的 \(beg_v\) 在遍历右端点时加入,若当前位置 为 \(beg_v\), 那就只能填这个数,否则在线段树上找 \([a_i,m]\) 的最小值并把 \(a_i\) 设为这个值,最后用树状数组统计一下逆序对即可。