一些题(九)
[CF1034E] Little C Loves 3 III
\(O(n^22^n)\) 的子集卷积看起来就很没救,所以要利用 \(\bmod 4\) 的性质。记 \(cnt(x)\) 为 \(x\) 二进制下 \(1\) 的个数,设 \(a'_i=a_i\cdot4^{cnt(i)}\),\(b',c'\) 同理。那么 \(c'_i\equiv \sum_{j|k=i}a'_jb'_k\pmod 4\),因为 \([j\&k=0]=[cnt(i)=cnt(j)+cnt(k)]={4^{cnt(j)}4^{cnt(k)}\over 4^{cnt(i)}}\bmod 4\)。于是在 long long 范围内做一个集合并卷积就行了。
https://codeforces.com/contest/1034/submission/143306690
[JOI 2021 Final] ロボット
注意到当每条边只会进行一次操作,因为有足够多的颜色可以用。所以考虑走一条 \((u,v,c,w)\) 的边的代价,要么花费 \(w\) 改这条边,要么花费 \(s_{u,c}-w\) 改 \(u\) 连出的其它颜色为 \(c\) 的边,其中 \(s_{u,c}\) 表示 \(u\) 连出的颜色为 \(c\) 的边的颜色和。但还需要考虑连走两条相同颜色的边,如果后一条边用第二种方法,那前一条边可以不用管。于是可以对于 \(u\) 通过颜色为 \(c\) 的边连接到的所有点两两连一条有向边,但这样边数太多,建虚点就行了。最后跑一个点数边数均为 \(O(n+m)\) 的最短路就好了。
https://www.luogu.com.cn/record/67127443
[AGC055E] Set Merging
一个非常神仙的转化:考虑一个排列 \(p\),初始 \(p_i=i\),在不进行无效操作的情况下将每步操作变为 \(\operatorname{swap}(p_i,p_{i+1})\),最后的 \([L_i,R_i]=[\min_{x\ge i}p_x,\max_{x\le i}p_x]\)。正确性我会感性理解。
那么问题就变为了给定前缀最大值和后缀最小值,求逆序对最小的排列。可以填完一定确定的位置后贪心,注意判无解,最后算一下逆序对数即可。
https://atcoder.jp/contests/agc055/submissions/28600148
[AGC056E] Cheese
设 \(c_i\) 表示坐标 \(i\) 个放了 \(i\) 个奶酪,\(x\) 表示所有奶酪共经过 \(-0.1\) 点 \(x\) 次,此时第 \(i\) 只老鼠会被经过 \(b_i=x-i-\sum_{j=0}^i c_i\) 次。那么最后剩下第 \(n-1\) 只老鼠的概率是 \(2^{-b_{n-1}}\prod_{i\le n-2}(1-2^{-b_i})\),再乘上 \(c_i\) 对应的概率 \((n-1)!\prod{(a_i\%)^{c_i}\over c_i!}\),并对 \(\sum c_i=n-1,x\ge 0\) 求和就是答案。
但可能出现某个 \(b<0\) 的情况,不过由于 \(b_i\le b_{i+1}+1\) 和 \(b_0\ge 0\),所以一定存在另一个 \(b=0\),于是这项的贡献为 \(0\)。另外,这种计算方法不会忽略一些在单独绕圈的奶酪,每绕一圈就要乘 \(1/2\) 的概率(不能被第 \(n-1\) 只老鼠吃),所以答案要除 \(1+{1\over 2}+\cdots=2\)。
这个式子能写成关于 \(2^{-x}\) 的多项式,可以 \(O(n^4)\) dp 求出,然后根据 \(\sum_{x\ge 0}2^{-ix}=1/(1-2^i)\) 就能得到答案。对每只老鼠做一遍,总时间复杂度 \(O(n^5)\)。
https://atcoder.jp/contests/agc056/submissions/28621328
[KEYENCE PC 2021] Keyence Repetition
考虑设给定串的第 \(i\) 个字符出现在第 \(a_i\) 个 keyence
的第 \(b_i\) 个位置,那么就有 \(a_i+[b_i\ge b_{i+1}]\le a_{i+1}\),所以只要考虑有几个 \(b_i\ge b_{i+1}\) 就能求出答案。由于 k
、y
、n
、c
的 \(b\) 已经固定,而 e
有三种可能,所以只用求出每个 e
连续段关于 \(b_i\ge b_{i+1}\) 个数的生成函数。这个容易分治 NTT,最后把生成函数乘起来也可以分治 NTT。
[UR #18] 绝对不鸽
考虑一个向右无限长的格子,把 \(a\) 不升序排列填在最左的位置上,剩下的位置是 \(0\)。那么一轮操作相当于往最左 \(n\) 个数中在不破坏有序的情况下加 \(A\) 个 \(1\),然后移除最左边 \(B\) 个格子。
考虑枚举 \(k=xB+1\) 表示答案在第 \(k\) 个位置取到,那么每轮操作一定是不停地给第 \(k\) 大 \(+1\),重复 \(A\) 次。这样需要枚举的 \(k\) 有很多,但发现当 \(k>n+B\) 的时候一开始的 \(a\) 的贡献已经没用了,相当于 \(a_i=0\) 的情况。所以只用管 \(k\le n\),因为 \(k\in (n,n+B]\) 时可以先模拟一轮操作。
考虑如何算答案,设 \(f_i\) 表示剩 \(iB+1\) 个数,答案钦定在第 \(iB+1\) 位,且这些数平均分布,它们的和的最大值。对于枚举的 \(k\),若干轮后一定存在一个 \(l\),使得 \([l,k]\) 的平均分布(极差 \(\le 1\)),这容易二分求出,那么它就可以更新某个 \(f\)。另外,还要考虑进行很多轮后的情况(即 \(k>n+B\)),此时最优的局面是稳定在 \(n-B\) 个 \(\lfloor(A-1)/B\rfloor\) 和 \(B\) 个 \(0\),也可以以次更新 \(f\)。
最后再进行一轮 dp \(f_{i-1}\gets \max\{f_{i-1},\lfloor f_i/(iB+1)\rfloor\cdot((i-1)B+1)+\max\{0,(f_i\bmod (iB+1))-B\}+A\}\),答案即为 \(f_0\)。时间复杂度 \(O(n\log n)\),可以将二分 \(l\) 的过程改为双指针以减小常数。
https://uoj.ac/submission/527909
[UR #22] 月球列车
考虑 \(a_i+v\) 的第 \(j\) 位,为 \(a_i\oplus v\) 的第 \(j\) 位异或上 \(a_i+v\) 的前 \(j-1\) 位是否进位。发现进位当且仅当 \(a_i\bmod 2^j\ge 2^j-(v\bmod 2^j)\),于是可以预处理 \(\{b_{j,i}\}\) 表示 \(a_i\bmod 2^j\) 排序后的数组,然后询问时二分,时间复杂度 \(O((n+m)\log a\log n)\)。
考虑优化,发现求 \(b_j\) 时可以把 \(b_{j-1}\) 按照第 \(j\) 位的值分成两半然后直接拼接。二分的过程也可以通过预处理 \(c_{j,i}\) 表示 \(b_{j,1\ldots i}\) 中有多少第 \(j+1\) 位为 \(1\),并以次从小到大递推出每位会有多少进位。这样时空复杂度就变成了 \(O((n+m)\log a)\)。
https://uoj.ac/submission/528303
[Ynoi2006] rmpq
分块,对每 \(B\) 个修改预处理出它把平面分成的 \(O(B^2)\) 个区域以及每个区域要乘上的值。如果暴力做的话是 \(O(B^3)\) 的,可以考虑分治,复杂度是 \(T(B)=2T(B/2)+O(B^2)\implies T(B)=O(B^2)\)。但题目强制在线,所以需要用二进制分组来代替这个分治。对于询问,在它之前的每个块中找到对应区域的值(可以直接二分),将他们乘起来即可,乘法次数 \(O(n(n/B+\log B))\)。取 \(B=O(\sqrt{n})\),总乘法次数 \(O(n\sqrt{n})\),但常数较小,能过。
https://www.luogu.com.cn/record/66984130
[Ynoi2008] rrusq
离线后左端点从右往左扫同时维护每个右端点的答案,就只用处理类似区间染色的问题,可以用 k-d tree 进行。由于 k-d tree 会把一个矩形拆出 \(O(\sqrt{n})\) 个,所以总共要进行 \(O(m\sqrt{n})\) 次单点修改和 \(O(q)\) 次前缀和查询,可以值域分块均摊掉。