CF Round 1058(#2159) 总结
CF Round 1058(#2159) 总结
A
从左到右扫一次,维护一个待询问集合 \(S\),若 \(q(S\cup i)=v\ne 0\) 则 \(a_i=v\) 第二次出现,否则将 \(i\) 加入 \(S\),这样所有 \(1\sim n\) 都确定了一个位置。
对于没有被确定的位置,用确定的 \(n\) 个位置与它们挨个询问就可以确定它们的值,询问次数 \(3n\)。
B
不妨设 \(n>m\),发现 \(m\le 500\)。考虑枚举两列,找到所有合法的行,只有相邻的合法行会最为最优矩形,找合法矩形是 \(O(nm^2)\) 的。
考虑怎样对矩形内更新贡献,可以对每行 \(i\) 设 \(f_{i,l,r}\) 表示包含 \([l,r]\) 的矩形的最值, 这样合法矩形可以枚举其所有行更新 \(f\),对于两列来说均摊是 \(O(n)\)。
最后再转移 \(f\),即 \(f_{i,l,r}\gets \min(f_{i,l-1,r},f_{i,l,r+1})\)。时空复杂度 \(O(nm\sqrt {nm})\)。
C
发现如果 \(i,j\) 满足 \(a_i=j,a_j=i\),那么这两位就合法了。猜想合法情况就是像这样两两配对或单独 \(a_i=i\)。
但是发现还有特殊情况,可以有多个 \(i\) 满足 \(a_i=0\),此时 \(a_0=\sum [a_i=0]i\)。
去掉假的 \(-1\),剩下每个 \(-1\) 有三种情况可以选择:\(a_i=0\)、\(a_i=i\)、找另一个 \(-1\) 配对。这可以递推,设 \(f_i\) 表示有 \(i\) 个 \(-1\) 时的方案数,则 \(f_{i}=(i-1)f_{i-2}+2f_{i-1}\)。
当 \(a_n=-1\) 时要去掉 \(a_n=0\) 的方案,减掉指定其等于 \(0\) 时的方案数即可。复杂度 \(O(n)\)。
D1 & D2
发现一些性质:
- \(f(a[l\dots r])\le f(a[l-1\dots r])\)。
- 计算 \(f(a)\) 时可以只保留严格后缀最小值(会变成严格递增序列),最优代价不变。
- \(f(a)\) 最大大约是 \(2\log a_n\),具体来说每次找到最左的使得 \(cost\le 2\) 的位置分割,那么发现 \(a\) 会至少除以 2。
- 最优划分中,一定有 \(cost\le 3\)。这比较难发现,证明考虑如果有倍数为 \(X\ge 4\),那么我们一定可以找到满足条件的 \(x,y\) 使得 \(x\times y \ge X,x+y\le X,1\le x,y<X\),一种构造就是 \(x=\lceil\dfrac X 2\rceil,y=2\),然后从 \(x\) 倍开始划分。不断这样分割最后一定有 \(cost\le 3\)。
知道第二三个性质就可以直接做 D1,维护 \(O(\log n)\) 个指针每次移到当前 \(a_i\) 的若干倍数的位置,然后对这些位置转移,可以做到 \(O(n\log n)\)。加上第四个性质后,就只用转移 \(O(1)\) 个位置,复杂度 \(O(n)\)。
考虑 D2,由于第一个和第三个性质,我们可以对每个右端点求出 \(f(a[l\dots r])\) 相同的 \(l\) 的区间,这样的区间只有 \(O(\log V)\) 个。具体来说,每次 \(r\gets r+1\) 时先单调栈维护后缀最小值,然后我们只在所有后缀最小值上考虑。记 \(L(c)\) 为 \(f(a[l\dots r])=c\) 的最小 \(l\),初始 \(L(0)=r+1\),然后每次运用第四个性质从 \(L(c-1/2/3)\) 转移过来,这还需要对于每个位置 \(i\) 预处理最左的使得 \(cost(l,i)\le 1/2/3\) 的 \(l\)。复杂度 \(O(n\log V)\),有一些细节。
E
记 \(G(n)\) 为满足 \([x^k]G(n)=\sum _{i=0}^k [x^i]F(n)\) 的多项式,我们每次询问要求 \([x^k]G(n)\)。
\(G\) 其实满足 \(G(n+m)=G(n)F(m),\forall n,m\ge 0\)。
考虑分块,指定一个块长 \(B\),预处理所有 \(G(kB)\) 和 \(F(i),0\le i<B\)。\(F(i)\) 可以 \(B^2\) 预处理,考虑 \(G\)。
直接乘法是很慢的,而且模数是 \(10^9+7\)。考虑先求 \(F(kB)\),可以对 \(F(n+1)\) 的不同形式求导:
联立得,\(nF(n)F(1)'=F(n)'F(1)\)。
由于 \(F(1)=c+bx+ax^2,F(1)'=b+2ax\),所以讨论 \(F(n)\) 某一位的系数得,其中 \(A_i=[x^i] F(n)\):
移项得
处理 \(A_0,A_1\) 即可递推,于是处理 \(G(kB)\) 可以做到 \(O(\dfrac {n^2}B)\)。
总复杂度 \(O(qB+\dfrac {n^2}B+B^2)\),取 \(B=\sqrt n\) 可以做到 \(O((q+n)\sqrt n)\)。
F
发现性质:对于 \(f(l,t)\) 在任意 \(t\in[i, i+l]\) 都是单谷。证明考虑若存在 \(f(l,t)<f(l,t+1)\),则 \(t+1\) 时刻的头的位置一定前面 \(l\) 个位置的最大值,并且发现在 \(t+1\sim t+l\) 时刻都有 \(f> f(l,t)\),那么从 \(t\) 开始是不下降的,反过来也一样。则从长为 \(l+1\) 的区间内取最小值,往两边都是不下降的。
那么考虑对所有 \(t\) 每 \(l+1\) 个分段,总段数是 \(O(n\log n)\)。考虑三分找到这些段的谷,然后把它们插进堆里,每次取出后就把相邻插进堆里,这样就可做到询问数为 \(O(n\log ^2n+m)\)。
考虑怎么三分,考虑对于 \(f(M_1)=f(M_2)\),怎么确认往哪边缩。我们找到 \(a_{i,j}=f(M_1)\) 的位置,那么 \(t=i+j-1\) 时第一次覆盖 \(a_{i,j}\),则发现 \(t=i+j-2\) 时,\(f(t)\ne f(M_1)\),于是比较大小即可。
那么我们就发现其实可以不用找到 \(M_1,M_2\),每次只要找到 \(mid\),比较 \(f(i+j-2)\) 与 \(f(mid)\) 的大小即可,这其实是二分。

浙公网安备 33010602011771号