2018各省省选选解
Update on 2024.5.9
这篇文章之前是我 2023-02-06 21:54 时发布的,当时最后更新于 2023-02-12 12:56,是去年省选前我训练的内容。
现在因为某些原因,回来加训了,所以重新发布一下,顺带修一下以前文章挂掉的图。
请期待文章更新!
Old Part
没写题解不意味着没做,有的忘了写或者太草率了就算了。
部分前言删了。
HNOI/AHOI 转盘
题解
非常有趣。
考虑如下事实:最优解下,你总可以不停下。
因为,如果 \(s_i=s_{i-1}\),直接将前 \(i-1\) 秒都前移一位即可,显然不劣。
枚举终点 \(j\),设 \(i\) 到 \(j\) 的步数为 \(d(i,j)=\begin{cases}j-i&i\le j\\ j+n-i&i>j\end{cases}\),则得到解为 \(\min_j\max_id(i,j)+T_i\)。
也即,答案可以描述为
考虑怎么维护这个东西。
以下从 \(0\) 标号,区间左闭右开。
设 \(B_i=T_i-i\),我们考虑把这个东西这么描述
而答案即为 \(f(0,n)\)。
这个就,灰常的,兔队线段树啊!
我们考虑如何用 \(f(l,mid)\) 与 \(f(mid,r)\) 合并出 \(f(l,r)\)。
考虑分治时这个 \(g\) 会影响哪些部分的答案。
也即,我们要支持快速查询
\(v\ge n+g(l,r)\) 时,显然 \(f(l,r,v)=l+v\)。
则
设 \(h(l,r)=f(l,mid,g(mid,r)+n)\),则每轮只会递归到一侧,故单次修改复杂度 \(O(\log^2n)\)。
总而言之,我们得到
总复杂度 \(O((n+m)\log^2n)\),实现得好可以做到 \(O(n\log n+m\log^2n)\)。
HNOI/AHOI 毒瘤
题解
即给你一张联通图,满足 \(r=m-n+1\le11\),问有多少种选取独立集的方案。
Tarjan 做生成树,然后得到 \(r\) 条非树边。
直接状压树形 dp 的复杂度是 \(O(n2^r)\) 的,肯定跑不动。
考虑怎么优化。
考虑容斥,强制钦定某些非树边被选,这个可以 ddp 维护。
直接做就完了。
强制选时为
否则为
即,分别为
然后直接维护即可。
总复杂度可以做到 \(O(n+2^r\log n)\)。
HNOI/AHOI 游戏
题解
有趣的思维题。
考虑这么办:把不设限的缩点,称钥匙在左边的锁为 \(\rightarrow\),在右边的为 \(\leftarrow\):因为反过来的方法一定不可走。
则,一个点可能到达的区间一定形如(\(\circ\) 表示当前点)
所以,如果 \(\circ\) 夹在两个一样的 \(\leftarrow\) 或 \(\rightarrow\) 之间,其只能往一个方向走,可以用 RMQ 查询 “这些锁对应的最左 / 右钥匙” 快速判断。
如果夹在 \(\leftarrow\) 和 \(\rightarrow\) 之间,考虑暴力移动来预处理,则复杂度可以均摊。
使用 ST 表实现 RMQ 即为 \(O(n\log n+q)\)。
使用四毛子,总复杂度可以做到 \(O(n+q)\)。
然而由于要 RMQ,常数还是太大了。
考虑优化复杂度。
考虑对 \(\leftarrow\circ\leftarrow\) 仔细观察,容易发现这个东西的可行区间是单调的……
然后直接继承上一次的答案,直接递推即可。
总复杂度 \(O(n+q)\)。
HNOI/AHOI 排列
题解
高明的题目。
图论建图显然。
首先 naive 拓扑然后贪心是错的……
把带环的判掉无解,考虑到剩下的结构一定是一个森林。
考虑怎么处理。
方便起见,我们添加一个辅助根节点,使得整个结构变成一颗树。
合并两颗子树答案时,考虑到两者互不相关,可以用类似于“归并”的方式维护。
最后在开头加上根节点,同时维护单调栈。
这样的复杂度是 \(O(n^2)\) 的。
考虑优化,可以线段树合并,复杂度即为 \(O(n\log n)\) 或 \(O(n\log v)\)……
拜托!这个做法正确性是对的吗?
即,合并答案时,为啥是一个最优子结构?
不会证啊不会证,摆了。
来贺个题解做法。
按某个方向考虑权值。
我们把当前点的信息合并到父亲上,表示父亲已有信息取完后便取之。
这样,每个节点会被描述成一个节点列。
考虑怎样的儿子应当先选。
调整法指出,节点列的平均权值小的应当先选。
优先队列直接做即可。
使用并查集优化找当前父亲,堆寻找当前元素,复杂度 \(O(n\log n)\)。
这个做法其实也指出了上个做法是正确的:即,归并时应当使用平均值来归并,然后直接处理。不过线段树合并常数感觉会很大。
HNOI/AHOI 道路
题解
即分别选择一个不修。
\(abc\) 的贡献是常数,\(bcx\) 和 \(acy\) 的贡献分别上传到链上的每条边,\(cxy\) 的贡献为链上每对不修的边之间的贡献。
这个玩意感觉非常不好 dp……性质很差……网络流也建不出来……
我去。原来有特殊性质。
“任意乡村可以通过不超过 \(40\) 条道路到达首都。”
把每个节点到根的路径上有几条未修的公路 / 铁路计入状态就做完了。
即,设
答案即为 \(f_{1,0,0}\)。
设 \(d\le40\) 为深度,复杂度 \(O(nd^2)\)。
BJOI 求和
题解
普及组题。
注意到 \(k\) 很小,对每个幂次的自然幂和都预处理出前 \(n\) 项,容易做到 \(O(nk)\)。
然后预处理出每个点的深度,查询时直接找到 LCA 就做完了。
假设我们写了 \(O(n)-O(1)\) LCA,复杂度即为 \(O(nk+q)\)。
采用倍增 / 树剖 LCA,复杂度即为 \(O(nk+(n+q)\log n)\) / \(O(nk+q\log n)\)。
BJOI 二进制
题解
唔……很有意思啊!
容易发现
假设长为 \(n\),其中有 \(m\) 个 \(1\),则考虑找到可行的充要条件。
首先 \(2|m\) 时,奇偶位分别分配 \(\frac m2\) 个 \(1\) 即可;显然最优。
\(2\nmid m\) 时,分别分配 \(\frac{m+3}2\) 和 \(\frac{m-3}2\) 个 \(1\) 即可;显然最优。
也即,不可行当且仅当 \(m=1\),或者 \(2|n\land m=n-1\),或者 \(2\nmid n\land m=n\)。
正难则反,不妨转而统计不合法方案数。
考虑分别统计这几部分贡献:
- \(m=1\land n>2\)
- \(2|n\land m=n-1\)
- \(2\nmid n\land m=n\)
考虑如何分别统计。
对于 \(m=1\land n>2\),可以线段树维护如下信息:
- 当前区间有 \(0/1/\ge2\) 个 \(1\)。
- 当前区间的答案。
- 如果只有 \(1\) 个 \(1\),其的位置;
- 如果有多于 \(1\) 个 \(1\),其的首、末 \(1\) 位置,以及分别往内可以扩展多少 \(0\)。
这个东西可以快速合并,且有结合律。
对于 \(2|n\land m=n-1\),考虑这么维护:
- 当前区间有 \(0/1/\ge2\) 个 \(0\)。
- 当前区间的答案。
- 如果只有 \(1\) 个 \(0\),其的位置;
- 如果有多于 \(1\) 个 \(0\),其的首、末 \(0\) 位置,以及分别往内可以扩展多少 \(1\)。
对于 \(2\nmid n\land m=n\),考虑这么维护:
- 当前区间有无 \(0\)。
- 当前区间的答案。
- 如果有 \(0\),其的首、末 \(0\) 位置。
这些东西都是半群信息,可以在 \(O(1)\) 时间内快速合并,于是即可用线段树解决修改 / 查询问题。
单次操作复杂度均为 \(O(\log n)\)。
这样,本题就变成了基础线段树练习题啦!
只不过分类讨论有点恶心罢了……
代码实现较为复杂。
BJOI 染色
题解链接。(题解已死,有事烧香)
BJOI 链上二次求和
题解
没啥意思的拆贡献题……
假设元素依次为 \(a_1,a_2,\dots,a_n\),把询问差分一下,计算长度 \(\le r\) 的路径的贡献。(\(r\le n\))
先考虑长度 \(=d\) 的怎么算:
于是答案即
分类讨论:
\(2r\le n\) 时,答案即为
\(2r>n\) 时,答案也为此。
则单组查询分别可以表述为(不妨设为区间查询,也能做,查询 \(a_l\sim a_{r-1}\) 中长度 \(\le d\) 的权值和,\(n=r-l\))
考虑怎么计算。
考虑线段树维护区间和、区间等差数列和,动态修改前缀和,然后直接暴力计算每部分贡献即可。
具体来说,线段树要支持如下查询操作:
则答案可以表述为
所以就是如何计算 \(S,Q_1,Q_2\)。
修改随便处理一下就好了。(假设区间长度 \(n\),加 \(w\))
单次操作复杂度 \(O(\log n)\),由于时限较松,可以轻松通过。
BJOI 猜数
题解链接。
CQOI 交错序列
题解
以下认为 \(a,b\) 同阶。
这个,感觉,不是很懂啊!
答案可以直接被公式表述。
这种东西一看就是满脸的不可做:只能线筛 \(O(n)\)(\(a,b\ll n\)),虽然能过此题但不优美。
幂是很难拆的,但这里形式特殊,能不能优化呢?
直接矩阵快速幂是 \(O(a^3\log v)\) 的,不优。
接下来就是优化后面一坨柿子,即
考虑到,这个东西实际上就是
考虑把
提取前若干项系数。怎么做?
先考察
的封闭形式。
使用插板法的组合意义可以分析,其结果是
即求
的前少数项。
考虑一个域的扩:\(f+g\sqrt{1+4e^z}\),这个东西容易维护。
由于题目中给的是一个素数域,计算难度不难不易,可以把每个系数用 \(a\times m^b\) 描述,最后乘阶乘时还原即可。
但是上面的做法就是一个说的道理,考虑怎么写的阳间一点。
总所周知有 EI technique Binomial Sum 大法,其指出
这样其实只用算出
最后计算
即可。
这么做甚至可以直接模合数操作(\(2\) 的逆元可能得要特殊处理一下),可谓是非常轻松啊!
总复杂度 \(O(a^2\log n)\)。
关于如何特殊处理 \(2\) 的逆元:
我们把每个 poly 用
\[\frac{A+B\sqrt{5+4z}}2 \]表示,然后乘法容易合并。
\[\frac{A+B\sqrt{5+4z}}2\frac{C+D\sqrt{5+4z}}2\\=\frac{AC+(5+4z)BD+(AD+BC)\sqrt{5+4z}}4 \]由于题目中给出的柿子对于不同的 \(n\) 总是整数,因此上面的柿子在模数是 \(2\) 倍数时系数总是 \(2\) 的倍数!
这样就做到了一个合理的合并。
另一种做法:
其实,我们根本不用分解到通项式!
分式基形式,上常系数齐次线性递推即可。
没有脑子,矩阵快速幂即可。
计算过程中进行取模,复杂度依旧为 \(O(a^2\log n)\)。
常数会大几倍,但很好写,也不用考虑 \(2\) 的逆元问题,这就很好了。
使用一些方式可以进行卡常,从而跑得飞快。
HAOI 苹果树
题解链接。
HAOI 奇怪的背包
题解链接。
HAOI 字串覆盖
题解
特殊性质明示正解……
设 \(X=50,Y=2000\)。
考虑对 \(P\) 的串长根号分治。
然后进行一个剪花布条的贪心:每次把能覆盖的最小位置覆盖掉。
当 \(|P|>Y\) 时,考虑暴力找到每次能匹配的最小位置,就是 SA 上区间查询大于等于某个数的最小数,直接主席树即可维护;由于匹配次数不超过 \(\frac nY\),其单次询问复杂度即为 \(O(\frac nY\log n)\)。
当 \(|P|\le X\) 时,注意到原串中每一个长度对应的串均不超过 \(O(n)\) 个,对那些串可以预处理答案,其余均无解。
或者说,预处理出每个串的“下一个匹配位”所在的位置,则该结构构成森林,直接把询问离线下来 dfs 一遍森林,同时树上差分,对末位二分即可得解(不知道为啥大家都写的倍增,明明离线下来多好写)。
构建树的过程可以做字符串哈希,哈希表维护找父亲,预处理复杂度 \(O(nX)\),单组询问 \(O(\log n)\)。
对 \(X<|P|\le Y\),由于询问保证均匀随机,考虑用第一种算法,单次期望复杂度为
微调一下阈值,总复杂度较难描述,称为 \(O(\text{能过})\) 好了。
如果本题不保证特殊性质,该做法的复杂度即为 \(O(n\sqrt{q\log n})\)。
JSOI 防御网络
题解
题目给了一个点仙人掌。考虑怎么做。
把计算期望变成计算总和。
考虑反向统计贡献。
非环边的贡献:
假设两侧节点数分别为 \(a,n-a\),其会被选择 \((2^a-1)(2^{n-a}-1)\) 次。
环的贡献:
假设各节点外延节点数分别为 \(a_1,a_2,\dots,a_m\),环长 \(d\)。
则每个部分存在被选节点的方法依次为 \(2^{a_1}-1,2^{a_2}-1,\dots,2^{a_m}-1\)。
考虑到,假如相邻被选节点的位置之间距离依次为 \(d_1,d_2,\dots,d_k\),则环上链接的长度应为 \(d-\max_jd_j\)。
我们计算对于每个 \(\max_jd_j\) 其有多少选法。
一种想法是容斥(差分),转化为 \(d_j\le L\)。
枚举最小选择元素 \(1\le s\le L\),对最后一个选择元素设状态,直接 dp。
显然可以用前缀和等优化到 \(O(n)\),然后就在 \(O(n^3)\) 内完成了单个环的答案。
总复杂度 \(O(n^3)\),已经可以通过。
优化到更优?我不会我不会。
递推的过程感觉可以直接表述成前缀和求单项,然后怎么来优化一个。
TBA
题解
鸽子啦!不做啦!
New Part
我回来了!
JSOI 列队
题解
萌萌题。
容易得到贪心算法:学生间的最短路不会出现迎面跨越和追逐跨越,容易证明这样可以得到一组最优解。
于是需要知道哪几个学生是向右走的,哪几个是向左走的。显然最终区间内存在一个位置(的相接处)满足其之前的向右,其之后的向左。
在主席树上二分即可做到单次询问 \(O(\log n)\) 的复杂度。
总复杂度 \(O(n\log n+q\log n)\)。
JXOI 排序问题
题解
容易发现,若设最终 \(v\) 的出现次数为 \(c_v\),那么轮数为 \((n+m)!/\prod c!\)。
为什么?考虑合法状态一定是所有相同的数连成一片,不同的数从小到大,从而相同的数内部顺序可以任意。故最后这个状态只有 \(\prod c!/(n+m)!\) 的概率被随机到,取倒数即为期望轮数。
而目的是最小化 \(\prod c_t!\),于是可以想到每次挑出一个出现次数最少的区间内的数将其加一。容易想到这个贪心是最优的。于是我们可以把出现次数最低的数同时向上抬高 \(1\)。
于是一开始预处理统计出区间内每种出现次数的数有几个即可。
复杂度容易做到 \(O(\max(n+m)) - O(n\log n)\),其中前者复杂度来自于预处理阶乘,后者可以用哈希表做到 \(O(n)\)。
JXOI 游戏
题解
考虑怎样的集合是合法的。
我们会发现,有的元素无论如何都必须选;而选了这些元素后,其倍数就不必被选。因此合法等价于这些元素都被选。
假设有 \(k\) 个这样的数,我们现在计数转期望,改为求每个前缀不合法的概率,于是即为
最后答案再乘上 \(n!\),即为
于是就做完了。
FJOI 领导集团问题
题解
先反转一下权值,方便分析。
考虑对每个子树维护一下对于每个答案,最大的值至少要多少。
容易发现这单调。
合并两个子树时只用归并,加上根时只用更新 upperbound 处值。
使用 Splay 维护,复杂度 \(O(n\log n)\)。
使用 multiset 树上启发式合并维护,复杂度 \(O(n\log^2n)\)。
FJOI 所罗门王的宝藏
题解
设第 \(i\) 行的贡献为 \(A_i\),第 \(j\) 列的贡献为 \(B_j\),则即若干条
的限制。
把其画作 \(n,m\) 的二分图上的一条边,我们发现只用对每一个联通块存在方案即可。
容易发现每个联通块可以左侧同加右侧同减,故答案若有解可总是整数。
于是对每个联通块假设左侧某个点权值为 \(0\),然后从其开始 dfs 确定其余值并校验合法性即可。
总复杂度 \(O(n+m+k)\)。
TJOI 教科书般的亵渎
题解
容易发现,划分出剩余血量的连续段后,每段是一起杀的。
去掉顶部不存在的 \(n\) 后,剩下的不存在数目加一即为操作次数。
于是即为求自然幂和,可以拉格朗日插值轻松解决。
SDOI 反回文串
题解
首先容易想到容斥。为了容斥,需要考虑这个回文是怎样的结构。
也即考虑多个回文中心的情况。
如果 \(n\) 是奇数,则对任意两个回文中心,其对应的回文串必定相同。证明是容易的。于是可以得到此时原串必定由 \(n/j\) 个长度为 \(j\) 的回文串拼成。于是易得此时答案为
其中 \(r_j\) 满足 \(\sum_{t|j,j|n}r_{n/j}=t\),即 \(\sum_{j|\frac nt}r_j=t\),故 \(r_j=n\times(\mu*\operatorname{id}^{-1})(j)\)。也即答案为
考虑 \(n\) 是偶数的情况,此时容易发现任何一个回文中心的对面还是一个回文中心,因此必定会有至少 \(2\) 个回文中心。实际上容易发现所有回文中心还是均匀分布(间距相同),从而必定是一个串翻前翻后的形式。
于是,若其为奇数个回文中心,其相邻之间的串必定是偶回文串,从而出现了新的回文中心,从而矛盾。故必定为偶数个回文中心。
考虑直接枚举所翻转的串的形态。
其中 \(u_j\) 满足 \(\sum_{t|j,2j|n,2t\nmid j}u_{n/j}=2t\),\(v_j\) 满足 \(\sum_{t|j,2\nmid j,j|n}v_{n/j}=t\)。
对于 \(j\) 满足 \(2^r|j\) 且 \(2^{r+1}\nmid j\),我们有
于是对于 \(2\nmid t\land t|n\),设 \(n\) 共有 \(r\) 个 \(2\) 因子,我们有
故第一部分即为
对于第二部分,我们注意到前面的系数与第一部分定义的唯一差异在于强制 \(v_j\) 的下标含有 \(2^r\) 个因子,因此等于
于是两部分贡献直接相加,可得答案为
直接解决即可。(事实上可以发现奇数情况的公式和此几乎完全一致)
由于总需要求 \(t(\mu*\operatorname{id}^{-1})(j)\) 状物,故需要使用依照积性函数原理的搜索来找出所有位置,故需要使用 Pollard-Rho 算法进行质因数分解。为了保证运算过程中不含除法,需要考虑将 \(t\cdot\operatorname{id}^{-1}\) 一起考虑。
本文来自博客园,作者:myee,转载请注明原文链接:https://www.cnblogs.com/myee/p/SX2018-record.html