个人难度:红橙橙黄绿绿
T1:模拟题 个人难度红
对于每一个 mmm 中的字符串,暴力检查是否和 nnn 中的字符串相同并打标记。
T2:思维题,个人难度橙。
首先分析题意:选出一个子序列,使得它们的gcd+1,求最终整个序列gcd的最大值。看到数据范围很容易想到枚举选出的子序列的gcd。接着考虑:含有这个枚举数作为因子的数必须全部选上,因为这必定是不劣的。再考虑剩下所有数的gcd,最终整个数列的gcd相当于对这两个数再取一次gcd,记录最大值即可。
T3:模拟题。个人难度橙。
常规思路是先考虑个位,统计所有可能的进位,如果进位的数不能直接凑出来就再考虑十位填数,以此类推...最多填8位。
但是我们手玩一下会发现如果有解,那么最短的解必定不超过2位数,相加的结果也就不会超过3位数。因此我们直接枚举 a,b,ca,b,ca,b,c,一共不超过 102×102×10310^2 \times 10^2 \times 10^3102×102×103 种情况,可以通过。
T4:dp题,个人难度黄。
首先很容易想到这是一个完全背包,但是价值的条件不一样。容易想到先钦定一个物品为幸福度较小的那个,然后贪心地找价格最小的与它配对。方法是按幸福度从大到小排序,记录当前扫到的物品的最小价格。将输入的价值加上配对物的价值作为最终价值跑完全背包即可。
T5:数据结构题,个人难度绿。
这题不少人可能会用线段树等做法做,但是我赛时没往这方向想,而是想到了值域树状数组+扫描线做法。
首先考虑:能与询问区间相交的区间分为3类:左端点在询问区间左边的,右端点在询问区间右边的,被询问区间完全包含的。(注意这三类可能有重复,但是这不重要,因为我们求的是最大值)
对于 1,21,21,2 两种情况,我们可以用前缀最大值 lmaxilmax_ilmaxi 表示左端点在 [1,i][1,i][1,i] 内的区间的右端点最大值,后缀最小值 rminirmin_irmini 同理。很容易想到以此计算出这两种情况的方法。对于第三种情况,我们把询问区间和给定区间按左端点从大到小排序,对于每一个扫到的区间左端点,在它的右端点处向树状数组添加它的长度(树状数组为取最大值的树状数组)。统计每个询问区间时查询以询问区间右端点为边界的树状数组最大值即可。
T6:计数题,个人难度绿。
首先考虑根节点怎么计数:使用树形dp,fif_ifi 表示以 iii 为根的子树的bfs序种类。首先预处理出每个节点子树大小 sizisiz_isizi ,接着我们发现我们每一步可以向任何一个子节点的子树前进一步,且bfs序长度恰为 sizisiz_isizi 。于是对于每个子树,我们在 sizi−1siz_i-1sizi −1 个位置里选择 sizvsiz_vsizv 个位置作为它子树bfs序的位置,再乘以内部排列顺序 fvf_vfv ,即:
fi=∑v∈soniCsizi−1sizv×fvf_i = \sum_{v\in son_i} C_{siz_i-1}^{siz_v} \times f_vfi =∑v∈soni Csizi −1sizv ×fv 。
接着考虑剩下的节点:对于某个节点 iii,我们可以在它原本的子树上扩展或是向它的父节点扩展。假设我们已经计算出父节点的最终答案 anspans_pansp ,那么向父节点扩展的方案数恰是 anspans_pansp 除去 iii 所在子树的情况。同样分析思路得:
ansi=ansp×sizin−sizians_i = \frac{ans_p\times siz_i}{n-siz_i}ansi =n−sizi ansp ×sizi
直接计算即可。