// 鼠标点击特效 //

杂题选做3

杂题选做3

QOJ2618

三个节点还是不好做,考虑仅有两个节点 \(x_1,x_2\) 该怎么做?

我们可以使用动态规划法来解决这个问题:设 \(f_{i,j}\) 表示还有 \(j\) 秒,此刻 \(x_1-x_2=i\) 的概率,转移可以枚举当前会发生的每一种状态:

\[f_{n,m}=\dfrac{1}{3}f_{n,m-1}+\dfrac{1}{3}(\dfrac{p}{100}f_{n+1,m-1}+\dfrac{100-p}{100}f_{n-1,m-1})+\dfrac{1}{3}(\dfrac{p}{100}f_{n-1,m-1}+\dfrac{100-p}{100}f_{n+1,m-1}) \]

整合一下:

\[f_{n,m}=\dfrac{1}{3}(f_{n,m-1}+f_{n-1,m-1}+f_{n+1,m-1}) \]

居然和 \(p\) 没关系,确实没关系。

但是这样直接做是 \(O(nk)\) 的,怎么办呢?发现这个转移明显是很多个多项式卷积得来的,分治fft优化一下既可以做到 \(O(n \log n)\)

现在有三个点 \(x_1,x_2,x_3\) ,该怎么办呢?发现这三个点之间的距离就是 \(x_1,x_2\) 的距离加上 \(x_1,x_3\) 的距离加上 \(x_2,x_3\) 的距离然后除二即可。所以解决了两个点就可以解决三个点。

时间复杂度 \(O(n \log n)\)

QOJ2605

逆天构造题。

合法点集的要求有点像选出二分图的左部和右部点,我们先对原图构造一张至少有 \(nk\) 条边的二分图:

按照编号从小到大进行二分图染色。对于节点 \(u\) ,仅考虑 \(v<u\)\((u,v)\) 有边的节点 \(v\) 构成的集合 \(s\) 。如果 \(s\) 中的点在二分图的左部更多,则将 \(u\) 放入二分图的右部;反之放入左部。

容易发现这样的构造,二分图的边数不会小于 \(\frac{m}{2}\) ,也就是 \(nk\)

接下来我们找到度数小于等于 \(k\) 的点,删除,一直循环直到所有节点度数都大于 \(k\) ,此时就是一组解。一个比较平凡的实现就是使用set维护所有节点的度数,然后每一次取出度数最小点进行修改一类,时间复杂度为 \(O((n+m) \log n)\) ;但是注意到,如果一个节点 \(u\) 的删除导致某些节点度数小于等于 \(k\) 了,那一定是与 \(u\) 直接相邻的节点,所以使用一个队列维护即可,时间复杂度为 \(O(n+m)\)

但是有没有一种可能,我们上面的流程把图删空了呢?其实是不可能的,假设当前还有 \(n\) 个点和至少 \(nk\) 条边,因为我们只会删除度数小于等于 \(k\) 的点,所以进入 \(n-1\) 个点的时候,也有至少 \((n-1)k\) 条边。我们归纳的证明,上述流程结束之前的任何时刻,假设目前有 \(n\) 个节点,就一定有至少 \(nk\) 条边。因为一定存在某一个时刻 \(nk>\frac{n(n-1)}{2}\) ,所以不会被删空。

QOJ1243

画图发现不会存在两个点 \(p,q\) ,两点均不是矩形的四个角。所以至多只有一个节点 \(p\) 不是矩形的四个角。我们枚举 \(p\) ,剩下的点只会出现在左对角/右对角中。分类讨论每一个矩形对 \(p\) ,左对角,右对角的覆盖情况:

  • 仅覆盖 \(p\) ,可以放入左对角和右对角。
  • 覆盖 \(p\) ,左对角,可以放入右对角。
  • 覆盖 \(p\) ,右对角,可以放入左对角。
  • 仅覆盖左对角,可以放入 \(p\) 或者右对角。
  • 仅覆盖右对角,可以放入 \(p\) 或者左对角。
  • \(p\) ,左对角和右对角都没有覆盖,可以放入 \(p\) 或者左对角或者右对角。

我们可以枚举上述 \(24\) 种情况进行计算。左右对角也分(左下角和右上角,左上角和右下角),所以一共 \(48\) 种情况。时间复杂度 \(O(XY+n)\)

QOJ7254

肯定考虑dp,关键在于如何去重。我们设 \(f_{i,j}\) 表示考虑 \(a\) 序列长度为 \(i\) 的前缀和 \(b\) 序列长度为 \(j\) 的前缀合并,可以得到多少种完全不同的序列。

一个最为基本的转移就是 \(f_{i,j}=f_{i-1,j}+f_{i,j-1}\)

这样算重复的原因就是,可能存在 \(a[1\dots i]\)\(b[1\dots j]\) 的一个长度为 \(k\) 的公共后缀。假设取完了 \(a[1\dots i-k]\)\(b[1\dots j-k]\) ,这样的后缀会使得答案算多因为可以让 \(a\)\(b\) 的操作交换。

得到一个转移:

\[f_{i,j}=f_{i-1,j}+f_{i,j-1}-\sum_{1 \leq k \leq \text{lcs}(i,j)} f_{i-k,j-k} \]

但是这样依然不对。假设取出了两个完全相同的,长度为 \(p\) 的后缀,也可能在转移过程中到达某一个状态 \(f_{i-q,j-q}\) ,其中 \(q<p\) 但是也是 \(a[1\dots i],b[1 \dots j]\) 的公共后缀。我们可以直接使用卡特兰数避免这种情况(折线图不允许触碰 \(x=y\))。

得到转移:

\[f_{i,j}=f_{i-1,j}+f_{i,j-1}-\sum_{1 \leq k \leq \text{lcs}(i,j)} f_{i-k,j-k}\times H(k-1) \]

最后分析一下时间复杂度,是 \(O(n^3)\) 吗?不对,因为排列的限制,所以对于一个前缀 \(a[1\dots i]\) ,仅有一个前缀 \(b[1\dots j]\) 满足 \(\text{lcs}(i,j) \neq 0\) ,所以时间复杂度应该是 \(O(n^2)\)

QOJ7308

打表发现:\(f_1=1,f_2=2,f_3=6,f_4=16\)

对于 \(n>4,f_n=2f_{n-1}+f_{n-3}+2\) ,使用矩阵优化。时间复杂度 \(O(T \log n)\)

QOJ1087

首先,这种二进制问题是优先考虑拆位的。我们看看这个问题在每一个二进制位的体现:

你需要给每一个位置赋予一个 \(01\) 权值,要求某些区间的权值全部是 \(1\);某些区间的位置中至少存在一个 \(0\)

先不考虑删除第 \(i\) 的限制的影响,对原问题求出是否有解。我们将“要求区间内部全是 \(1\)” 的限制优先考虑,先对 \(l_i,r_i\) 做区间覆盖,获得数组 \(a\) 。然后检录 “要求区间内部至少存在一个 \(0\)” 的限制的合法性。

现在讨论删除某一个限制的影响,根据删除的限制的种类分讨:

  • 删除的是“要求区间中间至少存在一个 \(0\)”的限制,那么对于 \(a\) 不会有任何改变。如果本身不合法的区间只有这一个,那么删除之后整个局面就会变得合法起来。

  • 删除的是“要求区间中间全部都是 \(1\)”的限制,那么会导致某一些 \(a_i\)\(1\) 变成 \(0\) ,哪些位置会从 \(1\) 变成 \(0\) ?就是被覆盖了恰好一次的位置,我们可以对于每一个限制,求出被 \([l_i,r_i]\) 覆盖,且仅被 \([l_i,r_i]\) 覆盖的下标集合 \(s\)

具体而言,先求出每一个位置的覆盖次数,然后寻找 \([l_i,r_i]\) 内仅被覆盖一次的位置,可以使用并查集之类的算法找到。

接下来,将 \(s\) 排序后得到数组 \(b\) 。认为 \(b_0=0,b_{|s|+1}=n+1\) 。如果存在某一个不合法的区间 \([l,r]\) ,满足 \(\forall i \in [0,|s|] ,b_i<l \leq r<b_{i+1}\) ,那么就说明这个区间内部依然全部是 \(1\)

我们考虑枚举每一个 \(i\) ,然后查询是否有区间被 \((b_i,b_{i+1})\) 包含,显然可以使用一个线段树维护。

时间复杂度 \(O(n \log n \log V)\)

posted @ 2024-12-25 21:01  dan-da-dan  阅读(42)  评论(0)    收藏  举报