十二省联考 2019 题解
Day1 B 字符串问题
朴素的想法是,建一张 \(n_a+n_b\) 个点的有向图 \(G\)。对于一个支配关系 \((x,y)\),从 \(x\) 向 \(y+n_a\) 连边。此外,枚举 \(1\le i\le n_b\),对于每个满足 \(B_i\) 是 \(A_j\) 前缀的 \(j\),从 \(i+n_a\) 向 \(j\) 连边。
若 \(G\) 内有环,则显然答案为 \(-1\)。否则,设点 \(u\) 的点权是 \([u\le n_a]\left(ra_u-la_u+1\right)\),只需求出该图上点权和最大的一条路径即可。
上述做法的复杂度瓶颈在于建图,考虑如何优化。对 \(S\) 的反串建出后缀树,考虑两个子串 \(S_{l_1\dots r_1},S_{l_2\dots r_2}\),设它们在反串后缀树上的点定位分别是 \(u_1,u_2\)。那么 \(S_{l_1\dots r_1}\) 是 \(S_{l_2\dots r_2}\) 的前缀,当且仅当:
- \(u_1\neq u_2\) 且 \(u_1\) 是 \(u_2\) 的祖先;
- 或者,\(u_1=u_2\) 且 \(r_1-l_1\le r_2-l_2\)。
考虑直接将后缀树的结构放进 \(G\) 中。设后缀树上共有 \(s\) 个节点,在 \(G\) 中新建 \(s\) 个节点并保留后缀树上的连边。对于每个 A 类串 \(A_i\),设其点定位是 \(u\),从 \(\mathrm{fa}_u\) 向 \(i\) 连边;对于每个 B 类串 \(B_j\),从 \(j+n_a\) 向其点定位连边。
此时只剩下在相同节点上的字符串没有处理了。对于每个点 \(u\),将所有点定位到 \(u\) 的字符串按照长度从小到大排序。对于每个串从它前面第一个 B 类串向它连边即可。
时间复杂度 \(O(|S|+m+(n_a+n_b)\log |S|)\)。
Day1 C 骗分过样例
1_998244353
直接快速幂。
1?
不知道模数,但模数比较小,直接枚举模数即可。
1?+
没想出来。
此时模数非常大,是 \(10^{18}\sim 10^{19}\) 级别的。考虑充分利用下发数据。对于每组 \((x_i,y_i)\) 表示 \(19^{x_i}\bmod p=y_i\),将它们按照 \(x_i\) 从小到大排序。考虑相邻的两个,一定有 \(y_i19^{x_{i+1}-x_i}\bmod p=y_{i+1}\)。也就是说,\(p\mid y_{i+1}-y_i19^{x_{i+1}-x_i}\)。找到所有这些数的最大公约数作为 \(p\) 即可。
1wa_998244353
观察数据,大概是 \(p=998244353\) 且暴力乘的时候没开 long long
。如果直接模拟可以过比较小的一档。
考虑一个数 \(x\) 在 int
下乘以 \(19\) 再模 \(p\) 会得到哪个数。这个得到的数几乎可以看作是在 \([-2^{31},2^{31}-1]\) 间随机生成的,于是根据生日悖论,在期望 \(\sqrt{2^{31}}\) 步后就可以走到环上。暴力找环即可。
2p / 2u
讲个笑话,我没看出来这是判断质数。
2p 和 2u 是给定一个区间 \([l,r]\) 满足 \(r-l\le 10^6\),求 \([l,r]\) 间所有整数是否是质数,或者求它们的莫比乌斯函数。
对于前两个点,有 \(r\le 10^{12}\),此时筛出 \([1,10^6]\) 间的质数,并区间筛 \([l,r]\) 即可。
莫比乌斯函数怎么区间筛?或者说,一般的积性函数怎么区间筛?
先筛出 \([1,\sqrt{r}]\) 间的所有质数,并用它们筛掉 \([l,r]\) 间所有数的 \(\le \sqrt{r}\) 的质因子。此时每个数至多剩一个质因子,可以直接特判掉。对于那些被筛掉的质因子,在筛它的过程中可以计算积性函数的值。
对于第三个点,对 \([1,10^8]\) 做一次区间筛,筛出 \([l,r]\) 的近似结果。此时错误的地方已经不多了,可以直接打表。
2g
给定区间 \([l,r]\) 和质数 \(p\),求 \([l,r]\) 中每个整数是否是模 \(p\) 的原根。对于第一个测试点,有 \(p=998244353,r-l\le 10^6\);第二个测试点有 \(p=13123111,l=1,r=p\)。
有两种判定原根的做法,分别对应这两个测试点。
2g?
现在不知道模数了。但我们知道模数是 \([10^9,2\times 10^9]\) 间的一个质数。所以筛出该区间的所有质数,逐一用 2g 的方法判断即可。
因为不满足条件的质数一定会在一开始就被判掉,所以跑得很快。
Day2 A 皮配
记题目中给的 \(k\) 是 \(K\)。
假如 \(K=0\),则每个学校选择哪个派系,和每个城市选择哪个阵营,是独立的。也就是说,可以对学校和城市分别做背包,乘起来就是答案。
注意到 \(K\) 很小,可以把包含这 \(K\) 个偏好的城市和学校拿出来单独计算。先用 \(K=0\) 的做法算出 \(F_j\) 表示那些没有偏好的城市中,选择大小之和为 \(j\) 的加入蓝阵营的方案数;以及 \(G_k\) 表示那些没有偏好的学校中,选择大小之和为 \(k\) 的加入鸭派系的方案数。
然后对有偏好的单独 DP。考虑这样一种 DP 顺序:
- 先加入没有偏好的城市和学校;
- 对于每个有偏好的城市,将它放在它所包含的有偏好的学校前加入。
设 \(f_{i,j,k,0/1}\) 表示考虑前 \(i\) 个有偏好的城市或学校,城市选了大小之和为 \(j\) 的加入蓝阵营,学校选了大小之和为 \(k\) 的加入鸭派系,且当前学校所在的城市选择加入蓝/红阵营的方案数。初始值是 \(f_{0,j,k,0}=F_jG_k\)。
这样可以做到 \(O(Km^2)\)。再注意到,由于 \(s_i\le 10\),所以学校那一维新加入的部分不超过 \(10K\le 300\)。所以更改一下 DP 顺序,将没有偏好的学校放在最后加入,即可做到 \(O(nm+K^2sm)\)。
Day2 B 春节十二响
考虑如何求出一个子树的答案。这肯定就是,为根节点单独分配一块内存,然后把所有子树需要的内存的对应位置取个 \(\max\)。用启发式合并维护这个东西,时间复杂度 \(O(n\log n)\)。
Day2 C 希望
绝望。