Hey Gift:Tryna tryna against the tite

UOI2024

P12552 [UOI 2024] Points on a Line

随机化。考虑随机排列的严格前缀 \(\max\) 只有 \(\mathcal O(\log)\) 个,前缀 \(\min\) 同理,故我们随机一个顺序往里面加入点只有 \(\mathcal O(\log)\) 次向外扩张。由于判定一个点不值得被加入只需要一次,但判定一个点扩张需要两次,所以大概是 \(n+4\log\) 的。

P12553 [UOI 2024] Lady's Gift

我的做法不太本质。

考虑 \(q=0\) 实际上非常简单,考虑此时不用确定字符只需确定指向,而 \(i\) 的下一步是 \(j\) 当且仅当 \(s_i[0,3n-1]\)\(s_j[1,3n]\) 相等,因为这样不在环上的部分是对的,而在环上的部分因为两者共享了至少长度为 \(2n\) 的环的部分,最小周期也是固定了的。

\(q>0\) 考虑如果一个串 \(i\) 找不到指向,那么我们就直接拿一个没有确定的串过来,通过得到 \(s_i\) 的最小周期把这个串构造出来,然后接着做。显然这样是下界的。

P12554 [UOI 2024] Queries for Subarray Beauty

这题有任何不黑的道理吗。

还没有彻底搞懂怎么单 \(\log\),咕咕咕。

P12555 [UOI 2024] AND Array

简单题。

我的做法。好像还可以定期重构的说。

P12556 [UOI 2024] Colorful Table

哎我草这个抽屉原理怎么这么难。

考虑 \(c=2\) 时我们可以简单地用抽屉原理证明,\(01\) 交替和 \(10\) 交替就能轻易取到答案。考虑对棋盘黑白染色,然后建立黑白到 \(\{0,1\}\) 的映射:

  • \(\{0,1\}\to \{1,0\}\),贡献产生自 \((0,0)(1,1)\)
  • \(\{0,1\}\to \{0,1\}\),贡献产生自 \((0,1)(1,0)\)

这两瓣加起来是 \(nm\),所以这两个就是 \(\le\left\lfloor\frac{nm}{2}\right\rfloor\)

考虑 \(c=3\),我们猜测还是只染两种颜色,考虑六种可能 \(\{0,1\}\to \{x,y\},\forall 0\le x,y\le 2\land x\ne y\),可以发现一共六瓣,加起来是 \(4nm\),所以做到了 \(\le\left\lfloor\frac{2nm}{3}\right\rfloor\)

考虑再进一步。可以发现如果这样交替,那么我们确定了其中一种颜色,实际上另一种颜色可以是另外两个的任何一个,不必都是同样的。这样还是六瓣,但可以发现做贡献的加起来只有 \(3nm\) 了,于是完成构造。

P12557 [UOI 2024] Football

简单题。我的题解

P12558 [UOI 2024] Heroes and Monsters

精妙啊。

显然要先两个序列排序。然后考虑一个显然的 \(\mathcal O(n^3)\) 做法:枚举选中的集合大小,那么相当于整个 \(b\) 切成一个长度为 \(k\) 的前缀和一个长度为 \(n-k\) 的后缀,把 \(a\) 里面选中的和没选中的放进去做归并式贪心。我们在 \(a\) 中从小到大选,选上的放进前缀对应比较,没选上的放进后缀对应比较。\(i,j,k\) 三个一个都省不掉,复杂度 \(\mathcal O(n^3)\) 无法优化。

然后,然后就卡住了。考虑限制分离办法,考虑把 \(a\) 也按照 \(b_k\) 分开成前缀和后缀,这样的好处是 \(a\) 后缀里面只要选了就一定可行,\(a\) 前缀里面只要不选也一定可行,而且这两者根本不关心在归并贪心里面往哪里放,所以就是各自对对面没有限制。

对于这种两种变量的限制问题,限制较为复杂。但是你发现,某一段对一个变量实际上是没有限制的,而另一段对另一个没有限制。那么你就应该把它们分离看。
—— 题解

于是我们分开对两侧 dp,两边分别不用管对面的事情就可以 \(\mathcal O(n^2)\),最后统计答案的时候枚举断点,合并两边的 dp 值就可以了。合并时注意我们是已知选择的集合大小的,所以枚举其中一边的选择数量就可以了。

总复杂度 \(\mathcal O(n^2)\)

感觉做法一出来就有点熟悉。忘记在哪里见过类似的东西了。

P12559 [UOI 2024] Zeroing the segment

黑题放了。

P11536 [NOISG 2023 Finals] Curtains

最讨厌补题了。

考虑一个区间 \([s_i,e_i]\) 如何有解。当然是对于其中任意一个点 \(x\) 都有至少一个区间 \([l_i,r_i]\) 使得 \(s_i\le l_i\le x\le r_i\le e_i\)。不妨同时离线区间和询问,这样可以轻易解决 \(r_i\le e_i\) 的限制。我们只需查询 \([s_i,e_i]\) 中所有点是否都存在一个 \(l_i\) 包含它且 \(\ge s_i\)

考虑在扫描线过程中维护加入区间,这只需要对 \([l_i,r_i]\) 中的所有点和 \(l_i\)\(\max\),支持查询区间 \(\min\) 即可。

区间 \(\max\) 并查询区间 \(\min\) 只需线段树即可。

QOJ1427. Flip

最讨厌补题了。

考虑不要数概率,我们直接考虑每种正反面情况的概率是 \(2^{2n}\),只需考虑有多少种正反面使得所有问到的人都在同一边就行了。

考虑是对称的,所以我们钦定所有问到的人都在 \(1\)。那么丢到的正反面的形式就形如:一个前缀是 \(1\),剩下那个后缀丢到了 \(2\)\(2\) 满了不得不去 \(1\),所以是随意的。其中这个前缀和后缀都可以是空的。

不妨枚举第一个 \(2\) 出现的位置 \(i\),钦定在这里数到序列。考虑此时的限制:\(i\) 前面必须有至少 \(n\)\(2\)。可以发现这同时意味了 \(i-1\) 及其前面的 \(1\) 都是合法的,因为两边不能同时满。故我们考虑枚举其前面 \(2\) 的数量:

\[\sum\limits_{i=1}^k \sum\limits_{j=n}^{a_i-i}{a_i-i\choose j}2^{2n-a_i} \]

当然还需要处理没有任何一个 \(2\) 的 corner case:

\[\sum\limits_{j=k}^{n}{a_k-k\choose j-k}2^{2n-a_k} \]

于是我们得到 \(\mathcal O(nk)\) 获得答案的式子:

\[2^{2n-a_k}\sum\limits_{j=k}^{n}{a_k-k\choose j-k}+\sum\limits_{i=1}^k2^{2n-a_i}\sum\limits_{j=n}^{a_i-i}{a_i-i\choose j} \]

考虑怎么把它变为 \(\mathcal O(k)\)。容易发现后面可以应用差分:

\[2^{2n-a_k}\sum\limits_{j=0}^{n-k}{a_k-k\choose j}+\sum\limits_{i=1}^k2^{2n-a_i}(\sum\limits_{j=0}^{a_i-i}{a_i-i\choose j}-\sum\limits_{j=0}^{n-1}{a_i-i\choose j}) \]

显然地我们实际上只需计算:

\[2^{2n-a_k}\sum\limits_{j=0}^{n-k}{a_k-k\choose j}+\sum\limits_{i=1}^k2^{2n-i}-2^{2n-a_i}\sum\limits_{j=0}^{n-1}{a_i-i\choose j} \]

ph 给出了一个基于递推求 \(\sum\limits_{j=0}^{n-1}{x\choose j}\) 的方法(本质上是下文的莫队固定 \(l\)),可以直接计算右边的和式,对左边的和式应用差分后可以在 \(\mathcal O(k)\) 时间内算出。但是我们想要在线!

考虑左侧。容易发现这是一个组合数行前缀和,我们考虑莫队(假设 \(a_k\) 最先输入,即 \(a_k\) 可离线)。此时我们会加入所有 \(i=1,2,\cdots,k\) 的询问 \([l=n-i,r=a_k-i]\),查询 \(\sum\limits_{j=0}^l{r\choose j}\)

于是我们就在 \(\mathcal O(n\sqrt \sum)\) 解决了问题。

能不能再快一点?

显然把所有和式全部放进莫队是愚蠢的。因为对于同一个询问来说其实我们一直在查询 \([l,r],[l-1,r-1],[l-2,r-2]\) 这样的区间,而这样的区间在莫队转移中是 \(\mathcal O(1)\) 的。于是我们只需将每个询问的第一个询问,也即 \(\sum\limits_{j=0}^{n-1} {a_k-1\choose j}\) 算出来就完事了。算这个根本就不用莫队,我们沿用递推即可。

总时间复杂度 \(\mathcal O(n+\sum)\)。我们就简单地解决了先输入 \(a_k\),再升序输入 \(a_1,\cdots,a_{k-1}\) 版本的强制在线问题。

考虑正常的升序输入。考虑我们还是用类似莫队的结构维护左侧和式,可以发现 \(l\) 的变化是 \(\mathcal O(k)\) 的,而 \(r\) 的变化不易计算:若我们固定 \(l\),则扩展到 \(r\) 需要每次乘 \(2\),再减去一个移动前的 \(r\choose l\),类似那个递推。

事实上我们可以把 \(2\) 乘开,故只需计算减去的常数:

\[\sum\limits_{i=r'}^{r-1} 2^{r-i-1}{i\choose l} \]

进一步地考虑差分,然后倒过来,于是只需计算 \(\sum\limits_{i=l}^{r-1} 2^{i}{i\choose l}\)。显然可以分块,这样总复杂度是 \(\mathcal O(\sum \sqrt n)\) 的。

CF2118E Grid Coloring

闹剧。

首先你要会 \(n=1\),当然随便枚举两下就会了:从中间开始,每次往两边交替走就好了,这样可以生成一串 \(1\)

然后考虑 \(n\times m\),容易想到如果我先干掉外层那么内层的肯定就会往外层找,这样很坏了,但是如果我先把内层做好,让外层的都找外层的,最美好的就是每一层都独立掉,那我们就可以直接对每层应用基本构造了。

考虑怎么推广。

我们每次卸下周围一圈看上去比较复杂 场上我尝试这么做结果只解决了正方形,而且我不会扩张,考虑每次把一组对边加进来。可以发现加入对边的操作是类似的:我们先在某一侧的中间放置,再在对侧的中间放置,这样交替,注意一下顺序并且每次都加入一对短边(加一对长边显然有可能加到内部)就可以轻易做到每个点的权值 \(\le 2\)

因为向外扩张的第一步还是会导致加在内部,所以是 \(\le 3\) 的。

CF1942F Farmer John's Favorite Function

我会观察性质

考虑第一想法,足够长之后前面的影响其实就微乎甚微了。事实上,考虑 \(10^{18}\) 在六次根号(\(\log\log V\))后就只剩下 \(1\) 了,所以在 \(\mathcal O(1)\) 长度之内我们直接假装前面的东西不存在,得到的答案一定最多只比正确答案少 \(1\)

不妨假设这个长度是 \(B\)。相当于我们现在对整个序列分块了,我们每次只想知道最后的答案是谁。可以发现,最后是 \(v\) 还是 \(v+1\) 实际上取决于块前那个 \(f\) 是多少。显然是单调的,所以实际上每个块 \([l,l+B)\) 是个分段函数的意味:

\[f(l-1)\in[0,k] \to v\\ f(l-1)\in(k,10^{18}]\to v+1 \]

这种问题就很典了。显然我们确定了 \(f(0)=0\),所以我们可以 \(\mathcal O(\frac{n}{B})\) 地扫一遍所有块查询,修改时只需 \(\mathcal O(B\log V)\) 地二分这个界然后修改。取 \(B=\sqrt n\) 有最优。最后一块可能不够长度(可能导致影响无法完全削掉),单独暴力就好了。

但是可以发现何必分块呢。这个东西显然可以在线段树上合并上去吧!于是我们其实可以 \(\mathcal O(\log n)\) 查询,\(\mathcal O(B\log V)\) 修改。只不过最后一块还是要单独做就是了。取 \(B=\mathcal O(1)\) 就很快。

我是数据结构领域大神

我是 ds 大神,我会换维!

考虑离线,在时间维上维护数据结构,扫描下标轴。可以发现一堆单点修改本质上是 \(\mathcal O(n+q)\) 个区间加/减,往下一个位置挪的时候需要全局开根号。UOJ #228. 基础数据结构练习题 告诉我们,带有区间加的全局开根势能仍然是正确的。

Solution of UOJ #228. 基础数据结构练习题

考虑势能线段树,一个简单的想法是如果 \(\max=\min\) 那么区间加对这个区间没用,并且我们无需再开下去了,然而这样是错的。当出现 \(k^2,k^2+1,k^2,\cdots\) 这样 \(\max-\min=1\) 的序列时就倒闭了,我们暴力开完这个区间之后它可以又用一次区间加弄回来,事实上特判这种情况即可。

可以证明,复杂度是 \(\mathcal O(n\log n\log\log V)\) 的。

势能分析证明

取节点势能 \(\phi=\log\log(\max-\min)\)

显然,这样设计的好处是区间加不会增加节点的势能。而每开一次根,节点势能会变为 \(\log\log(\sqrt \max-\sqrt \min)\)。对于 \(\max-\min>1\) 的情况,这个值至少减小了 \(1\)(可以发现 \(\max-\min=1\) 的情况有可能不变,就是上面的特殊情况)。所以由于实际上我们总的势能只有 \(\mathcal O(n\log\log V)\),复杂度就是 \(\mathcal O(n\log n\log\log V)\)

当然也可以使用分块等办法暴力地解决。

CF1956F Nene and the Passing Game

临门一脚?临门一脚!

考虑对可以互相传球的人之间连边,那么我们显然只需要数连通块数。考虑一个思路框架:按照某种方式扫描所有的点,考虑将它合并给已有的连通块。只要保证每次都合并到复杂度显然就是对的。

那么考虑怎样的两个点可以合并呢:

\[|i-j|\in[l_i+l_j,r_i+r_j] \]

显然在连边时我们只需找出单向关系,于是改写成:

\[i-j\in[l_i+l_j,r_i+r_j] \]

这两个点 \(i,j\) 连双向边就可以了。

显然这是一个二维偏序的连边法。那么做法呼之欲出了:我们可以考虑离线,扫描其中一维作为合并顺序,另一维用 set 维护每一个连通块另一维的 \(\min\) 方便快速找到合并就行了。

CF1830D Mex Tree

容易想到树形 dp,考虑我们直接按照 \(\operatorname{mex}=0/1/2\) 进行 dp 比较复杂,所以 trickily,我们先钦定整棵树自然是一种情况,然后对剩下两种情况 dp 一下就好了。

枚举可以发现,我们应该设置整棵树上的路径都是 \(2\),即答案为 \(2(\frac{n(n-1)}{2}+n)=n(n+1)\)。此时我们只需考虑一条路径上颜色相同产生的负贡献,这个看起来性质就好一些。

考虑 \(f_{i,j,0/1}\) 表示子树 \(i\) 里面和根相连的同色连通块大小为 \(j\),颜色为 \(0/1\),此时的最小负贡献。直接子树合并 dp 是 \(\mathcal O(n^2)\) 的,无法通过。

还记得 NOIP2023 之前有一道题吗?那道题是一个链剖分的树形 dp 黑题,贡献产生自链切换。我们可以优化第二维,因为我们发现轻重链剖分是一个解,所以最优解不会超过树剖,也就是 \(\mathcal O(\log)\) 次轻重链切换!这样就把第二维优化到 \(\mathcal O(\log)\) 了。

这里也是同样的套路。我们考虑这个题的一个解是交替染色(树一定是二分图),此时产生的负贡献是 \(cnt_0+2cnt_1\),不超过 \(2n\)。换句话说,我们 dp 算出的值超过 \(2n\) 一定没用。进一步,这意味着,dp 中连通块的大小至多是 \(2\sqrt {n}\) 的,因为一个同色连通块至少会产生 \(\frac{siz^2}{2}\) 的负贡献!

于是我们直接做那个 dp,但是第二维只取到 \(2\sqrt{n}\)。根据树形背包复杂度,是 \(\mathcal O(n\sqrt n)\) 的。

然后,然后空间就炸了。我们根本开不下 \(\mathcal O(n\sqrt n)\) 的任何数组。考虑我们一个点上的 dp 数组大小只有 \(\sqrt siz\),程序中同时存在 dp 数组的点的 \(\sum siz\) 肯定是不交的,所以 \(\le n\),于是我们直接动态开空间,用完的清掉,就是 \(\mathcal O(n)\) 空间了。需要注意实现时释放 vector 需使用 .shrink_to_fit() 才能完全释放内存池。

CF200A Cinema

分块高手是暴力低手,*2400 拼尽全力无法战胜。

考虑一个显然的想法:曼哈顿距离是平方式增长的。换句话说,周围最多只有 \(\sqrt k\) 范围内的一个正方形中有解。所以我们赫然可以枚举竖着的 \(y\) 坐标,此时只需要找出 \(y\) 这一行上距离 \((x_0,y)\) 最近的点,使用链表或者并查集维护连续段就可以了。

对于在中间附近的点,因为周围没有遮挡,所以只需枚举到 \(\pm \sqrt k\) 就够了。但是对于靠近边界的点,因为有一部分点在边界外,所以我们枚举的行数会增加一些,这就有点倒闭了。

此时复杂度已经可以做到 \(\mathcal O(k\min(n,m)+nm)\) 了,但是我们希望复杂度是严格的 \(\mathcal O(k\sqrt k+nm)\)

考虑是不是真的会倒闭。如果我们的平面足够大,那么即使我们在边界上也有一侧 \(\mathcal O(\sqrt k)\) 的长度是存在的,于是我们仍然只需向两侧枚举 \(\mathcal O(\sqrt k)\) 个行。实现上,我们枚举行的距离 \(d\),查询 \(x\pm d\),用并查集维护即可。

考虑如果平面小到塞不下每行 \(\mathcal O(\sqrt k)\) 个点,证明这个方向上的边长都不到 \(\mathcal O(\sqrt k)\),那么我们直接枚举这一边就行了。这可以通过把矩形旋转到短边在左右,在短边上枚举距离实现。

P5776 [SNOI2013] Quare

复健耳分解。

考虑我们现在有 dp \(f_{S}\) 表示已经把点集 \(S\) 加入到图中,考虑如何增加一个耳。在发明耳分解的时候,会尝试 \(g_{S,u}\) 表示已有点集是 \(S\),新增耳加到点 \(u\),但是这行不通。因为我们必须要设定这个耳的终点在哪里,这样这个耳才能完整闭合。如果只要求耳走回 \(S\) 上的任意点,由于过程中耳上的点也被并入 \(S\),我们不难得到这样的“耳”:

image

于是设置 \(g_{S,u,v}\) 表示增加一条耳从 \(S\) 中的 \(u\to v\)。对于环状耳,设置 \(u=v\) 即可。

回到本题。我们希望加权重最少的边使得图是一个边双。我们知道,边双是可耳分解的。于是我们考虑进行耳分解 dp。

  • \(g_{S,u,u}\to f_S\),表示耳闭合了可以归入边双中确定的点了。
  • \(g_{S,u,v}\to g_{S\cup\{w\},w,v}\),其中限制 \(w\not\in S\),并且 \(w\)\(u\) 的邻域中。其实 \(w\) 回到 \(S\) 也没关系,但是这样方便理解我们的转移顺序。
  • \(f_S\to g_{S,u,v}(u\ne v)\),其中 \(u,v\in S\)。表示添加一个非环耳。
  • \(f_S\to g_{S\cup\{w_1,w_2\},w_1,w_2}(u=v)\),其中 \(u,v\in S\)。这里 \(w_1,w_2\) 都是 \(u\) 的邻域中不在 \(S\) 中的点,且这两个点来自于不同的边(可以相同,但是边必须不同)。之所以要提前走一步是因为我们不能接受同一条边被双向使用而理解成一个环:\(u\to w\to u\)

这样复杂度是 \(\mathcal O(2^{n}\text{Poly}(n))\),随便写写就过了。耳分这种东西只有调的时候才知道细节是什么……比如本题需要特意禁止 \(g_{S,u,u}\) 的转移,否则会一条边来回走两遍理解成环。

UTS2024

P12560 [UTS 2024] Randomized Palindromes

乱搞领域大神啊!

考虑这个东西有一个典的 dp 是 \(f_{x_1,y_1,x_2}\) 是否可行。其中由于 \(y_2\) 可以算出来所以直接从状态中省略。这样做是 \(\mathcal O(n^3)\) 的。

考虑一个猜测:数据是随机的,那么如果有答案的话应该会伴随出现大量的答案,虽然我完全不能理解这是怎么看出来的。所以我们只要检验一定数量的路径,就应该能检测到一个答案。于是我们只对 \(|x_1-y_1|\le 50,|x_2-y_2|\le 50\) 做上面的 dp 就好了。于是此时我们只需在状态中维护 \(x_1\) 和两个差值,就可以通过了。

P12561 [UTS 2024] Matrix

太神秘了!看不懂题解。

介绍一下本题比较牛的 \(\mathcal O(nm\log k)\) 做法。考虑一个直角边长为 \(k\) 的三角形可以拆成三部分:两个 \(\frac{k}{2}\) 的三角形,和一个 \(\frac{k}{2}\) 的正方形:

image

对三角形进一步递归地剖开,可以发现这些图形的大小只有 \(\mathcal O(\log k)\) 种。显然两部分都可以递归,\(\mathcal O(1)\) 地拆分再合并,于是做到了 \(\mathcal O(nm\log k)\)

P12562 [UTS 2024] Two Trees

答案是距离 \(u\to v\) 路径最近的关键点的距离 \(\times 2\),再加上 \(u\to v\) 路径的长度。

考虑操作分块,对于块外贡献,多源 BFS 后是一个路径求 \(\min\) 状物,我们可以使用树剖方法,这样预处理就是 \(\mathcal O(n)\) 了,总的就是 \(\mathcal O(\frac{n^2}{B})\)。块内贡献是容易计算的,只需要 \(\mathcal O(1)\) LCA 即可做到 \(\mathcal O(B^2)\)

总时间复杂度 \(\mathcal O(n\sqrt n)\)

P12563 [UTS 2024] Remove Node

乍一看没什么思路。套路地,由于操作完保留的权是 \(\min\),我们考虑找到全局最小值来考虑。

由于全局最小值永远摆在那里不会再变,所以我们不希望它合并给别人,而希望考虑别的连通块怎么合并给它。显然我们希望别的连通块越小越好,这样才能在合并全局最小值这里贡献更少。所以我们按照最小值点分治,每次把连通块最小值转成根,这样得到的就是合并树。做一次时间复杂度 \(\mathcal O(n^2)\),可以获得 \(4\) 分。

考虑优化这个东西。显然从贡献形式入手:每个点的点权其实在每个儿子处都被减了一次,只在父亲处加了一次。考虑把加减分开,加的部分就是点权和减去全局 \(\min\),减的部分是每个点的点权乘儿子数量。

乍一看儿子数量不好算,想到这里倒闭了。 实际上并非如此,考虑刻画儿子数。考虑一个点周围的点,点权小于它的显然不可能作为它的儿子,点权大于它的又一定还挂在它身上所以一定有一个儿子。唯一的问题来自点权相等的部分,我们需要钦定相等的点的选择顺序,不妨按照 DFS 序。故一个点的儿子数就是它邻域中点权大于它,或点权等于它但不是它父亲的点数。做一次时间复杂度 \(\mathcal O(n)\),可以获得 \(17\) 分。

然后考虑怎么维护这个玩意的区间查询和单点修改。显然把邻域拆成向上和向下维护,也就是一个点上维护父亲的信息和全部儿子的信息。维护儿子的部分,注意到每次单点修改只会修改一个点的儿子信息,父亲是一个点的所有点的父亲信息,还有一个单点不会变信息但需要重算答案。

维护父亲信息显然是简单的,直接修改即可。维护儿子信息只需对每个点的儿子开一个树状数组就好了,但是我嫌麻烦就写的动态开点线段树。注意子树查询时根的邻域不包括父亲。

维护总信息也只需要树状数组。反正就是一直写树状数组。

P12564 [UTS 2024] Jobs

太神秘。兄弟你题解呢?

CF1924C Fractal Origami

不是人的东西。

分析一下第二个图为什么会有蓝线。首先整个图的 diff 肯定都是由中间新增的正方形导致的,于是不妨从中间的正方形入手。模拟一下折叠的过程,可以发现我们实际上是在从中间的正方形开始延长新出现的折叠线,碰到边界就 \(45^{\circ}\) 反射,并且穿过一次过去的折叠线就反转一次颜色!

image

充分发扬人类智慧,可以发现从第二次开始新增的蓝线和绿线的长度和是相等的。利用刚才的刻画分奇偶讨论可以轻易地证明,但是如何能想到呢。

据此我们知道 \(V-M=2\sqrt 2\) 恒成立。于是我们只想算出 \(V+M\),也就是当前所有线的长度和。可以发现,第一次增加的是一倍的新正方形,第二次增加的是二倍的新正方形,第三次增加的是四倍的新正方形,于是我们猜测第 \(k\) 次增加的是 \(2^{k-1}\) 倍的新正方形。由于同时正方形的边长也即周长也在以每次 \(\frac{1}{\sqrt 2}\) 的速度减小,所以实际上第 \(k\) 次增加的长度就是 \(4\sqrt 2^{k-2}=2\sqrt 2^k\)

使用等比数列公式和快速幂可以快速求出第 \(k\) 次的总长度,然后解一下方程就做完了。

CF1924D Balanced Subsequences

显然考虑抽离这个 \(2k\) 长度的子序列,剩下的东西一定是 \(\texttt{)))}\dots \texttt{))((}\dots\texttt{(((}\)。直接把序列插进去肯定是不对的,显然会算重。

考虑在整体视角下计数,而不是把谁插进谁。容易想到尝试把两边的方案拆开算再乘起来:按照 \(\texttt{)))}\dots \texttt{))|((}\dots\texttt{(((}\) 这样分开,其中我们特别地规定左半边就截止在最后一个右括号。随后我们发现这个尝试具有美好的性质:对于那个长度为 \(2k\) 的合法子序列,如果其中有左括号在左侧、右括号在右侧的跨越式匹配,我们总是可以转化成没有这样跨越式匹配的情况。我们钦定在这种情况数到它,于是我们只需数在左侧或右侧插入完整的合法括号串的方案数。

先考虑左侧。不妨枚举左侧有多少个左括号,据此显然可以确定右括号的数量。然后考虑用折线去刻画使得左括号合法的方案数,容易发现和卡特兰数的过程是几乎一致的,反射容斥即可。特别地,左侧需要钦定掉最后一步,右侧没这个问题。

需要特判 \(m=k\),这种情况无法钦定左侧的最后一个右括号。

平方的范围好像是让类似 ddp 状的 dp 过的。

[UTPC2021 I] Card Decks

拜谢 DaydreamWarrior。太强大了。

显然地状压 dp 顺序。\(f_{S,i}\) 表示现在的前缀包含 \(S\),最后一项是 \(i\)。我们的转移是往后加一个 \(j\) 增长前缀,并覆盖所有可能的顺序。

考虑这样需要我们知道 \(i\to j\) 一路上需要对每个牌堆移动多少次。考虑 \(\mathcal O(nm^3)\) 预处理出所有可能的移动情况下所有牌被经过的次数,因为这里面有些已经被使用的牌不算经过次数了。于是我们可以 \(\mathcal O(nm^3)\) 预处理,dp 时 \(\mathcal O(m)\) 去掉被用过的牌产生的贡献,总复杂度 \(\mathcal O((n+2^m)m^3)\),时间和空间疑似都无法通过,不过好像使用 mitm 就可以过了。

考虑神秘结论。我们声称,对于确定的顺序 \(p_1,p_2,\cdots,p_m\),假设所有 \(n\) 个牌堆中 \(p_i\)\(p_{i-1}\) 上方 \(c_i\) 次,那么贡献 \((m-i+1)c_i\)。显然,\(m-i+1\)\(i-1\) 过后数组的长度。

考虑怎么理解这个。我们不要管 \(c_i\) 次,摊开单独来看每个牌堆循环位移的过程,把它刻画成一个指针在一个循环的数组向后移动,每次跳过已经消失的位置。可以发现每当 \(p_i\) 出现在 \(p_{i-1}\) 上方,我们就需要跨越一次两个数组的交界。我们在此刻计算上一个数组的贡献,显然就是 \(m-i+1\),因为之前删除和本轮删除的都不计入贡献。

CF1613F Tree Coloring

考虑容斥。我们首先在树上钦定一些链的颜色构成一个从上至下连续的东西。这个是简单的,我们设 \(dp_i\) 表示把树剖成点不相交的 \(i\)直上直下链的方案数,那么赋颜色的方案就有 \(i!dp_i\) 种。

显然算重了。因为可能会出现两根链颜色上连续,在树上也连续,但我们钦定它断开成两条链的情况。注意到每种赋颜色方案一定一一对应恰好一种极长链剖方案,于是不妨设 \(f_i\) 表示这个极长链剖方案剖成 \(i\) 根链,\(g_i=i!dp_i\) 表示这个链剖方案有 \(i\) 条链,但不一定是最少的。

类似二项式反演,我们容易得到 \(f,g\) 之间的式子:

\[g_i=\sum\limits_{j=1}^i {n-j\choose i-j}f_j \]

一个所有链都极长有 \(j\) 条链的方案,树上有 \(n-j\) 条边被链覆盖着。在这些边中选择 \(i-j\) 条断掉,链数就增加到 \(i\) 了。

我们希望求出 \(f_n\)

反演这个式子。猜测这个式子的反演形态和二项式反演应该差不多,于是:

\[f_i=\sum\limits_{j=1}^i(-1)^{i-j}{n-j\choose i-j}g_j \]

Proof by GPT o4-mini
翻转下标,令 \(f'_i=f_{n-i+1},g'_i=g_{n-i+1}\),然后考虑反演 \(f'\)\(g'\) 的新式子:

\[g'_i=\sum\limits_{j=i}^{n} {j-1\choose j-i}f'_j=\sum\limits_{j=i}^n{j-1\choose i-1}f'_j \]

注意到这就是朴素的二项式反演,只是所有下标后移了一位。于是我们有:

\[f'_i=\sum\limits_{j=i}^n(-1)^{j-i}{j-1\choose i-1}g'_j \]

将下标转回去即可得到原始的反演。

注意到 \(f_n\) 是一个特殊情况,反演等价于直接容斥原理。很显然对吧,说来也不知道为什么我会去想把所有答案都表示出来。

于是考虑如何求出 \(g_i\),即 \(dp_i\)。直接树形背包是 \(\mathcal O(n^2)\) 的,难以优化……吗?

不要忘记我们这里只有直上直下的链。考虑刻画一个剖分的性质,可以发现就是每个点选至多一个儿子,选儿子的方案和链剖分方案一一对应。于是我们规定在链底计数一条链,链数就是没有选儿子的点的数量,当然叶子选不了儿子就自然没有选儿子。于是这变成一个类背包问题,我们可以使用生成函数:第 \(i\) 个点的 GF 是 \(F(i)=x+son_i\),表示多一条链方案数不变,或者链数不变方案数乘儿子的数量。把这个东西全部乘起来,第 \(i\) 项的系数就是 \(g_i\)

暴力乘显然不行,最后会变成一个巨长的多项式乘一个一次多项式。所以使用分治 NTT 就好了,时间复杂度 \(\mathcal O(n\log^2n)\)。想求出所有 \(f\) 的答案只需再对着反演的式子做一次 NTT 即可。

实际上我们可以简单地做到 \(\mathcal O(n\log n)\)。我们把常数项相同的放在一起计算,不妨设有 \(c_i\) 个多项式常数项相同均为 \(s_i\),那么多项式 \((x+s_i)^{c_i}\) 可以用二项式定理直接算出系数。注意到关键限制 \(\sum c_is_i=n\),我们按照常数项从大到小排序暴力 NTT,这样 NTT 的次数就是 \(\sum\limits_{i=1}\sum\limits_{j<i} c_j=\sum\limits_{i=1}^n (n-i+1)c_i=\sum\limits_{i=1}^n c_is_i=n\) 了。

UOI2023

P12566 [UOI 2023] An Array and Several More Arrays

简单题。枚举顺序的全排列就做完了。

P12567 [UOI 2023] An Array of Coins and Weighing Requests

吊。

不妨先试试 \(k=1\)

考虑 \(3^9>10^4\),想到三分。

考虑在区间 \([l,r]\) 找出假币的位置。我们直接取 \(mid=\frac{r-l+1}{3}\),然后考虑 \([l,l+mid)\)\((r-mid,r]\),如果这两段都是相同的,证明假币在中间,否则证明假币在某一侧,递归下去即可。这样是 \(\log_3(n)\le 9\) 的。

我们考虑类似的想法,尝试处理 \(k>1\) 的问题。

我们只是希望 \([l,l+mid),[l+mid,r-mid],(r-mid,r]\) 这些区间当中最好是只有一个占了所有的假币,这样我们就能轻易地比较并收缩区间。不妨保证 \([l,r]\) 中始终有所有的假币,我们惊人地注意到,取 \(mid=\frac{r-l+1-k}{3}\) 时,我们有:

\[r-l+1-2mid=\frac{1}{3}len+\frac{2}{3}k \]

如果我们预先保证 \(r-l+1\ge k\),那么 \(\frac{1}{3}len\ge \frac{1}{3}k\Rightarrow\frac{1}{3}len+\frac{2}{3}k\ge k\)

进一步地这意味着,\([l+mid,r-mid]\) 这一段空当的长度是大于 \(k\) 的!也就是说,\([l,l+mid),(r-mid,r]\) 两者中至多有一个存在假币,我们可以轻易地找出到底是哪一段有假币。

然后考虑收缩,假设左侧有假币,那么我们显然只需收缩至 \([l,l+mid-1+k)\),右侧同理,如果是中间就收缩到 \([l+mid,r-mid]\)。考虑这样做我们每轮至少舍弃了 \(\frac{2}{3}\) 的真币,所以收缩 \(\log_3(n)\) 轮之后区间就只剩下 \(k\) 枚假币了,直接输出 \(l\) 就是答案。

P12568 [UOI 2023] An Array and Range Additions

考虑一个显然的想法:我们先把整个序列分段,满足每个段都没有相同的数。那么我们实际上只要使得这些段的 \(\Delta\) 互不相同就足够了。假设有 \(c\) 段,由于我们每次只能操作一个区间,可以发现除了 \(c=1\)\(\left\lfloor\frac{c-1}{2}+1\right\rfloor\) 个区间就能保证所有段上面覆盖的区间集合互不相同,故 \(\Delta\) 也互不相同。

然后这错了。注意到,如果两段里面包含的数没有交集,实际上我们不需要使得它们的 \(\Delta\) 互不相同。进一步地我们发现,如果这两段中有一段出现在中间是非常不优秀的,因为这意味着我们要截断整个区间覆盖使得这两段相同(显然为了这两段相同,中间的部分需要独立出来)。实际上只有这两段分别出现在首尾是有用的————这样我们可以通过把两头都不覆盖区间,来减少一段的长度。

进一步地等价,这等价于我们环状这个序列,求一个最小的分段数使得所有段内没有相同的数。

实际上到这里乱搞已经可以随便过了。我随机位移了一下序列再接个补丁就过了。我们考虑确定性做法。

考虑把两两相同的数中间画出一个区间,表示“这里必须分一次段”,那么我们实际上得到的是一对环状区间,它们意味着对于断点集 \(S\)

  • 正常的区间,\(\exist a\in S,l\le a\le r\)
  • 跨越环断点的区间,\(\exist a\in S,r\le a\lor a\le l\)

考虑第一种是经典贪心,我们按照 \(r\) 排序每次把断点丢在 \(r\) 上就行了。

然后考虑第二种怎么办。显然第二种只会导致我们最多增加 \(1\) 的答案:一开始的假做法就是强行选择 \(n\in S\) 来满足第二种限制导致的。所以我们只需考虑判定第二种区间能否导致我们不增加答案。

考虑我们先尽可能让第二种区间满足第二个部分的限制。我们希望找到一个最远的点使得它是所有断点中最小的,但从它开始第一种区间需要的端点数不会改变(改变就一定不优了)。显然这具有单调性,二分即可。

找到这个点之后,显然 \(l<a\) 的第二种区间就退化成第一种区间了。我们把它的第一部分限制放进贪心过程做一遍观察一下答案是否没有增加即可。

P12569 [UOI 2023] An Array and Partial Sums

黑色构造,鸽了。

P12570 [UOI 2023] An Array and Medians of Subarrays

简单观察,容易观察到分成超过两段没必要,因为任意两段中位数相同是可以合并的。于是只能分成两段,使用权值线段树维护前后缀即可。

P12571 [UOI 2023] An Array of Characters and Almost Palindromes

你们洛谷怎么不配交互库啊?害得我去 Eolymp 上做这题。

哎哎哎不会观察。

考虑我们只是需要保留下一个区间有有至多一个字符出现了奇数次。

特判掉区间本身就不行,如果没有任何一个字符出现奇数次,删去首尾中的一个就能规约到有一个字符出现了奇数次。

考虑有一个字符出现了奇数次怎么做。

有结论:一定删除这个字符偶数次再删恰好一个别的字符。

我们当然也可以删除这个字符奇数次,再删两个别的字符。但这显然是不优的:我要么不必删这个字符奇数次,要么不必多删一个别的字符。

于是只需考虑最少要删这个字符多少次可以删到别的字符。把两头拿出来讨论一下就好了。

P12572 [UOI 2023] An Array and Addition Again

简单构造题,拆拆位,然后多个位一起做卡一下位数到 \(<2\log\) 就好了。

P12573 [UOI 2023] An Array and XOR

感觉这种思维链比较长,转化比较多的题很容易卡。

先考虑 \(q=1,l=1,r=n\) 怎么做。

在二进制意义下做最值,容易想到按位贪心。这里数不是全集,所以想到 trie 树。

我们考虑按位确定答案。在 trie 树上沿着当前答案的前缀移动,考虑下一步如何向下:

  • 如果向下是零个儿子,显然返回作为答案。
  • 如果向下是一个儿子,考虑我们只需将当前取到该前缀的 \(x\) 下一位取反,就能构造得到下一位必然是 \(1\)。由于前面已经 \(\min\) 掉了,这里也不得不作为 \(\min\) 贡献出来,所以这一位在答案中必然是 \(1\)
  • 如果向下是两个儿子,考虑每个 \(x\) 总要选出一边作为 \(0\) 贡献成 \(\min\)。所以下一位上一定是 \(0\),再往后部分的 \(\max\) 就是递归下去两边子树的较大值(显然是一个独立的子问题)。

注意到这里存在递归返回的操作,我们反过来向上做。这样更好刻画,也更方便维护。设 \(dp_i\) 表示 \(i\) 子树内的答案,那么我们有:

  • 零个儿子,直接返回 \(0\)
  • 一个儿子,\(dp_i\gets dp_{son}+2^d\)\(d\) 表示向下那条边对应的二进制位。
  • 两个儿子,\(dp_i\gets \max(dp_{lson},dp_{rson})\)

这样就能做到 \(\mathcal O(nmq)\) 了,可以获得 \(21\) 分。

trickily,考虑拆开这个 \(\max\),我们变成所有叶子都允许往根贡献它到根的那条链,挑出其中最大的一个一定是答案。容易发现,一个叶子到根的链的贡献就是所有那些没有兄弟的点的深度的 \(2\) 次幂之和。我们考虑“没有兄弟”这个限制怎么刻画,显然对于每个叶子 \(i\),我们可以找出它祖先每个点 \(j\) 的兄弟在 \(i\) 之前的上一次出现位置 \(l_{ij}\) 和在 \(i\) 之后的下一次出现位置 \(r_{ij}\),那么这个点 \(j\) 没有兄弟当且仅当查询区间被 \((l_{ij},r_{ij})\) 包含。

然后考虑一个叶子的整个贡献方式。可以发现被包含是一个优美的结构,\(\mathcal O(m)\) 个祖先产生的 \(\mathcal O(m)\) 个区间至多只带来 \(\mathcal O(m^2)\) 种被包含的不同状态。注意到这 \(\mathcal O(m^2)\) 个状态由于包含关系所以具有不合法不优的性质,换句话说,我们可以直接把一个叶子的贡献方式拆成 \(\mathcal O(m^2)\) 个区间,最后我们只需要查所有包含查询区间的区间中权值最大的就行了。

于是考虑我们现在的贡献形式形如一个二维偏序:

  • \(l_{ij}\le l\le r\le r_{ij}\),只有完全包含询问区间的区间才能对应贡献。
  • \(l\le i\le r\),只有这个区间里的叶子允许贡献。但事实证明,这是一个不必要的限制。回到原来的暴力向上 dp 的做法进行考虑,可以发现即便我们允许超出范围的“不存在”的叶子进行贡献也显然不会影响答案。到这里问题都是等价转化,所以没有问题。

如果不考虑第二类限制没用,会产生一个 4-sides 的二维最值,非常难做。

考虑现在是一个 2-sides 的二维最值,离线加线段树即可做到 \(\mathcal O(q\log n+nm^2\log n)\),但是 \(nm^2\) 明显太大了,这个东西过不了。然而我们的修改是前后缀取 \(\max\),于是可以换成值域分块,做到 \(\mathcal O(q\sqrt n+nm^2)\) 就可以过了。

没完。你发现这题卡空间,我们没有办法给 trie 的每个节点开一个 vector 然后二分。于是要想找出左右第一个兄弟节点(\(l_{ij},r_{ij}\))只能在 trie 树上插两遍。

还是没完。你发现这题卡空间,我们没办法存下来所有 \(\mathcal O(nm^2)\) 个区间。这就有点恶心人了。

考虑我们求出这 \(\mathcal O(nm^2)\) 个区间 \([l,r]\) 的过程:本质上也是在求一个 \(l_{ij}\le l\le r\le r_{ij}\)\(w_i\) 之和。所以我们实际上也用到了离线来解决问题。

那么现在我们考虑把两块缝合在一起。最初我们是对 \(n\) 个叶子分别算出区间然后存下来,那我们现在把对 \(n\) 个叶子算区间的过程摊到询问的扫描线里面同时做,尝试获得对应左端点的所有区间。这只需要一边扫描线,一边维护所有叶子上 \(\mathcal O(m)\) 的信息就好了。

总复杂度 \(\mathcal O(nm^2+q\sqrt n)\)

posted @ 2025-06-01 08:26  Shunpower  阅读(14)  评论(0)    收藏  举报