小题狂练 (C)
好像其实是想新开一个的时候就开一个(
- [HEOI2014] 逻辑翻译
- [CEOI2013] Board
- [AGC002E] Candy Piles
- [APIO2022] 排列
- CF1615F LEGOndary Grandmaster
- [ICPC2016 WF] Swap Space
- [AGC040F] Two Pieces
- CF838F Expected Earnings
- [ABC304Ex] Constrained Topological Sort
- [集训队互测 2023] Tree Topological Order Counting
- [ARC067E] Grouping
- CF1375F Integer Game
- [AGC027D] Modulo Matrix
- [ARC089E] GraphXY
- CF17C Balance
- CF1733E Conveyor
- [HNOI2009] 有趣的数列
- P8864 「KDOI-03」序列变换
- [WC2019] 数树
- [AGC036D] Negative Cycle
- [CF16FinalG] Zigzag MST
- CF1693D Decinc Dividing
- CF1510I Is It Rated?
- 牛客多校 思
[HEOI2014] 逻辑翻译
考虑怎么让问题变得更小一点,比如尝试把 \(x_1\) 分离出来,答案多项式可以写成 \(x_1\cdot f(\bm x)+g(\bm x)\) 的形式,其中 \(\bm x\) 是 \(x_{2\dots n}\) 组成的向量 .
代入 \(x_1=1,-1\) 可以得到一个二元一次方程,求解即可让问题规模减半(也就是减一个未知数).
时间复杂度 \(\Theta(2^nn)\),输出比较麻烦 .
[CEOI2013] Board
懒得喷,注意到先上升到某一层然后平移过去下降一定最优,枚举层数即可 .
具体实现上需要先用一个只带 1 和 2 的序列描述两个点的位置 .
[AGC002E] Candy Piles
排序之后可以看成在 \(a\) 组成的杨表上走格路,从边界往回推就可以了 .
XXX
XXXXX
XXXXX
XXXXXXX
OXXXXXX
比如 \(3,5,5,7,7\) 的情况,相当于从 O
出发,1 操作就是往上走一步,2 操作就是往右走一步 .
另一侧的问题:Remove and Decrease Game .
[APIO2022] 排列
注意到一个长度为 \(k\) 的递增序列贡献 \(2^k\),考虑用一个递增的序列中间插递减序列来拆二进制位,这样是大概 \(2\lfloor\log_2k\rfloor\) 个元素 .
然而发现毒瘤出题人卡了常数,这里可以把递减序列中连续放的两个位置合并(并且抬高一点),这样就是约 \(1.5\lfloor\log_2k\rfloor\) 个元素,可以通过 .
CF1615F LEGOndary Grandmaster
很经典的题了,翻转奇数位后就变成每次把 1 移动一位,那么令 1 在两个序列中的的位置是 \(a_i, b_i\) 距离就是 \(\sum|a_i-b_i|\) .
那么只需要对于每个 \(i\) 枚举 \(a_i, b_i\) 计算其贡献即可 . 时间复杂度 \(\Theta(n^2)\) .
[ICPC2016 WF] Swap Space
感觉这个贪心策略有点神奇 . 断言:\(a_i<b_i\) 的按 \(a_i\) 从小到大选别的按 \(b_i\) 从大到小选 .
感性理解一波,显然 \(a_i<b_i\) 和 \(a_i\ge b_i\) 独立 . 对于 \(a_i<b_i\) 的情况格式化完 \(i\) 之后 \(i\) 这个位置就空了,所以主要关心当前产生的代价,也就是 \(a_i\);对于 \(a_i\ge b_i\) 的情况会使得总空间减少,所以主要关心造成的后续影响,也就是 \(b_i\) .
[AGC040F] Two Pieces
听说是多元 GF 经典例题(
就是要数形如 B(B(B(...(B
的结构,其中 B
是匹配括号串 .
用一个三元 GF,\(u,v,w\) 分别计量左括号个数、右括号个数和操作次数 .
\(C\) 是 Catatlan 数,则每段的 OGF \(G(u,v)=\dfrac1{1-v(1+C(uv))}\),仔细地刻画可以得到答案的 OGF:
代数推导部分开始:
注意到 \([x^a] x^kw^k(1 + C(xw^2))^{b - a + k} = w^{2a - k}[x^a]x^k(1 + C(x))^{b - a + k}\),那么可以得到:
在此处使用哑演算,令哑元 \(t=[x^a]x^k(1+C(x))^{b-a+k}\),则:
对于 \(t^k\) 可以通过另类拉格朗日反演求解:
那么就做完了,时间复杂度 \(\Theta(n)\) .
CF838F Expected Earnings
令 \(dp_{i,j}\) 表示取 \(i\) 个球,其中有 \(j\) 个红球时下一个球是红球的概率,有 \(dp\) 数组那么答案容易求得 .
那么转移就是:
注意到 Bayes 公式:
那么实际上只需要计算若干 \(i\) 个球中有 \(j\) 个红的概率,记为 \(t_{i,j}\),则可以转移:
那么整个问题就做完了,时间复杂度 \(\Theta(n^2)\) .
[ABC304Ex] Constrained Topological Sort
首先把限制变成最紧的,也即调整限制使得对于每条边 \((u,v)\),有 \(l_v>l_u\),\(r_u<r_v\),拓扑排序一下就可以了 .
做完之后只需要和选最多不交区间类似地按 \(r\) 扫一遍依次分配即可 .
[集训队互测 2023] Tree Topological Order Counting
只需要计算每个 \(u\) 排在拓扑序第 \(v\) 位的方案数 . 令 \(dp_{u,i}\) 表示考虑到 \(u\) 且 \(u\) 在第 \(i\) 位的方案数 .
则:
其中 \(C(u,v)\) 表示 \(u\) 除去子树 \(v\) 的拓扑序数量,可以预处理得到 . 那么这样做就 \(\Theta(n^3)\) 了 .
发现主要问题在于统计答案太慢,这里把这个 DP 倒过来就 \(\Theta(n^2)\) 了,可以看成对所有 \(u\) 一起做 DP .
[ARC067E] Grouping
\(ik\) 个人平均分成 \(k\) 组的方案数是
按组大小从小到大依次分配,令 \(dp_{i,j}\) 表示分到大小为 \(i\) 的组、还剩 \(j\) 个人的方案数,则可以简单转移:
不算快速幂的复杂度,时间复杂度 \(\Theta(n^2\log n)\)(调和级数).
CF1375F Integer Game
注意到当且仅当三个数组成等差数列且最大值不能操作时先手直接获胜 .
先随便操作一个比较大的数值使得形成一个最大值无法操作的状态,然后令三个数按顺序分别是 \(a,b,c\),取 \(k=2c-a-b\),分类讨论可得每种情况都构成等差数列 .
没错,三步之内先手必胜
[AGC027D] Modulo Matrix
考虑弱化到 \(\max(x,y)\bmod\min(x,y)=1\) .
黑白染色,钦定黑色取 max 白色取 min,那么黑色位置的值就是周围一圈白色的 lcm 加一 .
每条正 / 反对角线分配一个奇素数填上白色(每个白色位置由两个素数乘积组成),则每个黑色位置由四个素数乘积加一组成 . 调整素数顺序即可控制到 \(10^{15}\) 以内(交替放大小素数).
关于每个位置互不相同的证明:黑色和白色自身显然互不相同,而黑色位置一定是偶数、白色位置一定是奇数,显然不同 .
[ARC089E] GraphXY
令 \(f(i,j)\) 是 \(i-j\) 只算非未知数边的最短路,那么 \(d_{x,y}=\min\limits_{a,b}\{f(a,b)+ax+by\}\) .
弱化为 \(d_{x,y}\ge f(a,b)+ax+by\),取 \(f(a,b)=\max\limits_{x,y}\{d_{x,y}-ax-by\}\) 然后判断是否有位置能取到等号即可 .
要把这个构造放到图上,只需要连两条全是 X 或 Y 的链,然后在走 \(a\) 个 X 边到达的点和走 \(b\) 个 Y 边到达的点间连边权为 \(f(a,b)\) 的有向边即可 .
CF17C Balance
令一个串的核心是把他的连续段全部缩起来之后得到的序列(不关心连续段长度),则注意到操作后的序列的核心一定是原序列核心的子序列 .
那么就有一种生成所有操作后序列的方法了,然后做一个朴素 DP 就可以了,\(\Theta(n^4)\) 时间 .
CF1733E Conveyor
显然没有史莱姆会相撞,然后平方递推出到 \(t\) 时刻每个位置经过的史莱姆数和 \(t-1\) 时刻每个位置的史莱姆数然后比较一下即可 .
时间复杂度 \(\Theta(qn^2)\) 其中 \(n=120\) .
[HNOI2009] 有趣的数列
考察长度为 \(2n\) 的匹配括号序列,把左括号的位置放到序列的奇数位、右括号的位置放到序列的偶数位,则立得合法序列与匹配括号序列的双射,从而答案即为 Catalan 数 .
数据范围比较小直接 Legendre 公式线性对数做就可以通过了 .
P8864 「KDOI-03」序列变换
注意到操作相当于交换前缀异或和,那么原来的限制相当于限制 1 的连续段个数 .
令 \(a\) 是原来的 \(a\) 的前缀异或和,\(dp_{l,r,k}\) 表示将 \(l\dots r\) 中的 1 分为 \(k\) 段的最小操作次数,则:
其中 \(w_{l,r}\) 表示将 \((l,r]\) 中的 1 移动到同一段的最小操作次数 .
显然 \(w\) 满足区间包含单调性 . 另一方面,移动一个端点区间所有 1 的位置组成中位数位置最多移动一位,讨论一下可以得到 \(w_{l,r}+w_{l+1,r+1}\le w_{l+1,r}+w_{l,r+1}\),那么 \(w\) 也满足四边形不等式 . 从而 \(dp_{\dots,k}\) 和 \(w\) 都是蒙日矩阵 .
一次转移相当于做一个 \((\min,+)\) 矩阵乘法,矩阵快速幂即可批量进行转移,考虑到矩阵是蒙日矩阵所以这里的矩阵乘法可以 \(O(n^2)\) 计算 . 那么就 \(O(n^2\log k)\) 解决了这个问题 .
[WC2019] 数树
首先特判 \(y=1\) . \(\mathrm{op}=0\) 平凡不表 .
对于 \(\mathrm{op}=1\),相当于将蓝树划分若干个连通块,然后连一些边连通这些连通块(这里不能连原有的树边),假设连通块个数是 \(k\) 那么贡献 \(y^k\) .
考虑如果没有不能选原有的树边的限制就是一个 Prüfer 序列,答案是 \(n^{k-2}\prod s_i\),其中 \(s_i\) 是每个连通块大小 . 考虑这种计算方式相当于是每个合法方案贡献:
对于这个式子的解释就是钦定选 \(i\) 个树边计算有多少个选连通块的方案 .
那么先提出来 \((1+y)^n\),然后解方程 \(v^k(1+v)^{-k}=y^k\) 把贡献改成 \(v^k\) 就可以天然得到答案 . 从而问题变成一个大小为 \(s\) 的连通块贡献 \(snv\),一棵树的贡献是连通块贡献的乘积,求所有树的贡献和 . 注意到相当于在每个连通块里面选一个点然后贡献 \(nv\),用一个简单树形 DP 即可计算 .
对于 \(\mathrm{op}=2\),类似 \(\mathrm{op}=1\) 可以得到相当于每个大小为 \(s\) 的连通分量贡献 \(\dfrac{n^2y}{1-y}s^2\),算上生成树个数的贡献就是 \(\dfrac{n^2y}{1-y}s^s\),总体的答案就是这个东西的 MSET 构造,直接使用多项式 exp 计算即可做到线性对数 .
然而可以发现(joke3579:有标号有根树换元):
然后就可以线性做了 .
[AGC036D] Negative Cycle
模拟赛的有点深刻题 . 注意到如果保留 \(i\to j\) 的 \(-1\) 边,那么满足 \(i'\le i,\,j'\ge j\) 的连 \(i'\to j'\) 的 \(-1\) 边也一定保留,因为如果保留 \(i'\to j'\) 不合法那么保留 \(i\to j\) 也不合法,具体可以通过走 \([i',i),(j,j']\) 内的 \(0\) 边来考虑 .
那么可以发现 \(-1\) 边的结构一定是有一个 \([1,n]\) 的划分 \(I_{1\dots k}\),连任意 \(u\to v\) 其中 \(u\in I_p,\,v\in I_q\),这里 \(p<q\) . 进而可以得到 \(1\) 边就是连 \(u\to v\) 其中 \(u\in I_p,v\in I_q\),这里 \(0\le p-q\le 1\) .
可以用 \(dp_{l,r}\) 表示最后一个区间是 \(I_k=[l,r]\) 的答案,每次枚举上一个端点转移即可,时间复杂度 \(\Theta(n^3)\) .
[CF16FinalG] Zigzag MST
考察 \((a,b,c),(a+1,b,c+1),(a+1,b+1,c+2),\cdots\) 这组边,考虑 Kruskal 的过程,按边权顺序连边,连 \((a+1,b,c+1)\) 的时候一定已经连过 \((a,b,c)\) 了,那么 \(a,b\) 一定连通,可以把 \((a+1,b,c+1)\) 改成 \((a+1,a,c+1)\),答案不变 . 类似的,连 \((a+1,b+1,c+2)\) 的时候 \(a+1,b\) 一定连通,可以改成 \((b,b+1,c+2)\) . 不断这样改最后可以得到 \((a,b,c),(a,a+1,c+1),(a+1,a+2,c+3),\cdots,(b,b+1,c+2),(b+1,b+2,c+4),\cdots\) . 不考虑 \((a,b,c)\) 这条边,剩下的结构就是一个 \(2n\) 个点的环,可以简单叠合重边,这样就是 \(n+q\) 个点了,可以直接 Kruskal 求 MST .
时间复杂度 \(\Theta((n+q)\log(n+q))\),可以通过 .
CF1693D Decinc Dividing
定义 \(dp_{i,0/1}\) 表示 \(i\) 在递增/递减序列中时,另外一个序列最后一个元素的最大值/最小值 . 然后就能平方了 .
倒序枚举左端点,当某个 \(dp\) 值和上一次完全一致时直接继承上一次的右端点位置,然后就对了 . 因为注意到如果取 \(i\) 之前最大的 \(j\) 使得 \(a_j>a_{j+1}\) 那么 \(dp_{i,0}\) 只能是 \(\pm\infty,a_j,a_{j+1}\) 中的一个 . \(dp_{i,1}\) 类似 . 那么每个 \(dp\) 值最多被更新 7 次,所以时间复杂度是 \(\Theta(n)\) 的 .
CF1510I Is It Rated?
对每个人维护一个权值 \(p_i\),初始 \(p_i=1\),每次加权随机进行选择 . 公布答案后给所有选错的人的权值乘 \(0.8\) .
牛客多校 思
没报牛客多校,因为是模拟赛出的所以下面就按照模拟赛的配置说 .
考虑贡献是绝对值那么就分类讨论大小去掉 . 令 \(dp_{l,r,c}\) 表示当前 \(x\in[l,r]\),左边减右边的贡献是 \(c\) 的时候的答案 .
初始 \(dp_{i,i,c}=c\cdot a_i\),每次枚举一个询问的数 \(p\) 即可转移:
然后这个 DP 其实是有二维的决策单调性的,然后就可以 \(\Theta(n^2V)\) 了,可以获得暴力分 . 冷静一下发现 \(|c|\) 实际上是 \(\Theta(\log n)\) 级别的,那么就是 \(\Theta(n^2\log V)\) 了,可以通过 .
具体证明可以考虑一个长度为 \(V\) 的区间,每次如果查询 \(\dfrac 13V\) 左边的值那么右边最大产生 \(\dfrac23V\) 的代价,左边第一步最大产生 \(\dfrac13V\) 的代价,后面的代价不超过二分做的代价 \(\displaystyle\dfrac13V\sum_{k\ge 1}\dfrac1{2^k}=\dfrac13V\),那么可以把询问点调整到 \(\dfrac13V\),这样一定不劣 . 对称地可以得到询问点大于 \(\dfrac23V\) 的时候也可以调整到 \(\dfrac23V\),那么每次选的位置一定在 \(\left[\dfrac13V,\dfrac23V\right]\) 之间,也就是说区间长度每次至少缩小 \(\dfrac23\),那么肯定是 log 轮就结束了 .
虽然写一个一维的决策单调性分治 \(\Theta(n^2\log n\log v)\) 也可以直接冲过去 .
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/18178974
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ