『省选模拟赛1』 Day5 总结

前言

落日沉溺于橘色的海,晚风沦陷于赤诚的爱。

省流:省选集训,\(\texttt{BZ 13}\) 人,\(50+20+0=70\)\(\texttt{rk 11}\),因为有两个跟我并列倒一,真的糖丸了,低年级的也考不过。

T1 不会用 \(\text{Bitset}\) 查询最低位的 \(1\),即便不会,\(\mathcal{O}(\frac{n^3\times \log(n^2)}{\omega})\) 的极小常数二分做法也是可以通过的,但是我实现不够精细,导致暴力分都不如。

T2 分界点,我以为这个结论是错的,可能有些是第一种转移,有些是第二种转移,然后就否掉了。

T3 文件名打错了,\(\text{Tickets}\to \text{Ticket}\) 不知道是哪个唐氏出题人这么拼单词的。

真,糖丸了。

T1

不会使用 \(\text{Bitset}\) 以及实现不够精细,太菜啦。

首先显然有一个 \(\mathcal{O}(n^3)\) 的区间 DP,即定义 \(dp_{l,r}\) 表示删空这个子区间所需要的最小代价。

转移分为两种:

  • \(dp_{l,r}=\max\{dp_{l+1,r-1},\text{cost}(l,r)\}\)
  • \(dp_{l,r}=\min_{k=l+1}^{r-1}\max\{dp_{l,k},dp_{k+1,r}\}\)

实现常数足够小的话,应该可以除以一个 \(4\),能够惊险得到 \(70 \sim 80\) 的暴力分,而我多此一举的 \(\text{Bitset}\) 优化二分只有 \(50\),没救了。

考虑如何优化。

其实首先有一种,即从小到大枚举边权,每加入一条边看这条边可以扩展到多少 \(\text{DP}\) 值。

不过我们考虑另一种,即二分答案,然后将 \(dp_{l,r}\) 的定义转化为当前的边能否删空 \([l,r]\) 这个子区间。

考虑使用 \(\text{Bitset}\) 算贡献进行转移,应该单次 \(\text{Check}\) 可以做到 \(\mathcal{O}(\frac{n^3}{\omega})\)

总时间复杂度 \(\mathcal{O}(\frac{n^3\times \log(n^2)}{\omega})\),常数特别小可以通过。

\(\texttt{Code}\)

T2

告诉我们想到了什么奇葩结论就要敢于认为它是对的并去验证。

仍然先考虑暴力 DP。

首先,对于一堆 \((a_i,b_i)\),显然是按照 \(b_i\) 从大到小排序然后按照顺序选是最优的。

所以我们先按照 \(b_i\) 从大到小排序。

然后考虑定义 \(dp_{i,j}\) 表示前 \(i\) 个,选择 \(j\) 个,可以得到的最小 \(\sum_{i=1}^k a_{c_i}+b_{c_i}\times(i-1)\) 的值。

转移很简单:\(dp_{i,j}=\min \{dp_{i-1,j},dp_{i-1,j-1}+a_i+b_{i}\times (j-1)\}\)

时间复杂度 \(\mathcal{O}(n^2)\),可以通过滚动或者类似背包的转移顺序做到空间复杂度 \(\mathcal{O}(n)\),从而拿到前面 \(n\le 10^4\) 这一档分。

考虑如何对这个转移式子进行优化。

通过打表发现,对于每个 \(i\) 可以找到一个分界点 \(k\),使得 \(\forall j\in[0,k],dp_{i,j}=dp_{i-1,j},\forall j\in [k+1,i],dp_{i,j}=dp_{i-1,j-1}+a_i+b_i\times (j-1)\)

简单来说,就是每一个 \(i\) 所对应的所有的 \(j\) 的转移,前面一半是直接继承 \(i-1\),后面一半是直接把 \(i\) 加入进来。

故可以考虑使用平衡树优化 DP 来优化这个过程。

具体的,对于每个 \(i\),在转移之前先通过二分找到分界点 \(k\),然后将 \(k\) 这个点复制一份插在 \(k\) 后面,可以发现 \(k\) 后面的点会向后顺延从而下标对齐。紧接着,从复制点开始一直到最后一个点,其实本质上他们的增量数组是一个等差数列,这个应该可以通过一个普通的数据结构上的延迟标记来实现。

由于我太菜了,不会打平衡树,所以补题的时候用的块状链表来替代。

平衡树复杂度 \(\mathcal{O}(n\log ^2n)\),块状链表复杂度 \(\mathcal{O}(n\times \sqrt{n}\times \log n)\),实现精细的话单点查询可以做到 \(\mathcal{O}(1)\),从而总时间复杂度降为 \(\mathcal{O}(n\times \sqrt n)\)

听说有平衡树上二分的单 $\log $ 做法吗可惜我不会。

\(\texttt{Code}\)

T3

题解里面一堆这个题的相关结论,到时候再来看看。

稍微简单记一下吧,真要写起来还是太多了。

首先你最开始看上去只会 \(2^m\) 的搜索,即去对这个区间爆搜是翻转还是不翻转。

我们需要一个有前景的多项式做法。

考虑对于方案进行观察来找出一些限制。以下皆称翻转区间的方案集合为 \(S\)

\(\large \mathbf{Claim\ 0}\)

首先有一个为了方便叙述的东西要写在前面。

假设最终答案为 \(\text{ans}\),那么对于 \(\text{ans}' \ge \text{ans}\),这样的 \(\text{ans'}\) 是一定存在对应的方案的。(当然前提是你最大能凑的出来。)

证明感性理解,从 \(\text{ans}\) 中可以直接通过调整得到,主要是为了后面二分答案的正确性。

\(\large \mathbf{Claim\ 1}\)

对于任意一个答案最优的翻转集合 \(S\),必然不存在 \([a_1,b_1],[a_2,b_2]\in S\),且这两个区间不相交。

考虑反证,如果有一个集合 \(S\) 能够找到两个不相交的区间 \([a_1,b_1],[a_2,b_2]\),它显然不是最优的。

可以发现,如果我们不翻转这两个区间,会对答案造成一下变化:

  • \(i\in [a_1,b_1]\vee i\in [a_2,b_2]\),显然 \(i\) 的被覆盖的次数在翻转之后是不会变的。
  • \(i\notin [a_1,b_1]\wedge i\not \in [a_2,b_2]\),显然 \(i\) 的被覆盖次数会减少 \(2\)

可以发现这样的调整是不劣的,故上述性质是成立的。

\(\large \mathbf{Algorithm\ 1}\)

其实我们已经可以通过上面的结论推出第一个多项式复杂度的算法。

先给出一些定义:

  • \(p_i\) 表示点 \(i\) 在翻转了 \(S\) 内的区间之后,被覆盖的次数。
  • \(q_i\) 表示在 \(S\) 被翻转之前,\(i\) 被覆盖的次数。(这东西在区间输入完之后是一个定值。)
  • \(r_i\) 表示 \(i\) 号点在 \(S\) 内部的区间中,翻转前被覆盖的次数,形式化的:\(r_i=\sum_{[a,b]\in S}[i\in[a,b]]\)
  • \(I\) 表示 \(S\) 内所有区间的点的交集。(已经证明过必然存在交集。)

对于每个 \(S\),其对应的答案显然是 \(\max p_i\)

可以发现,对于每一种方案 \(S\),其实 \(p_i,q_i,r_i\) 是存在等量关系的:\(p_i=q_i-r_i+(|S|-r_i)=q_i+|S|-2\times r_i\)

对于 \(\forall i\in I\),其实也是存在等量关系的:\(r_i=|S|\)

为了去得到跟答案相关的 \(p_i\),直观的想法是枚举一个点 \(s\) 满足 \(s\in I\),然后为了得到 \(|S|\),再去枚举 \(r_s\)

我们发现,此时 \(\forall i\in [1,n],|S|,q_i\) 是确定的,为了得到 \(p_i\),我们还需要知道 \(r_i\),也就涉及到了我们对于 \(S\) 如何分配区间的问题。

不可能暴力去搜索,所以我们考虑二分答案 \(\text{mid}\)(在结论 \(0\) 中已经证明过一定能找出解,二分答案是正确的),显然只要满足 \(\forall i\in [1,n],\text{mid}\ge p_i\),那么该答案就是合法的。

我们要做的就是通过控制 \(r_i\) 去满足上面的条件。

观察到 \(r_i=\frac{q_i+|S|-p_i}{2}=\frac{q_i+r_s-p_i}{2}\),由于我们要让 \(p_i\le \text{mid}\),所以有 \(r_i\ge \frac{q_i+r_s-\text{mid}}{2}\)。我们要做的仅仅只是去让 \(r_i\) 达到这个下限。

于是有一个比较直观的贪心,考虑从 \(1\to s\) 依次枚举点,如果当前的 \(r_i\) 没有到达下限,那就找到当前可以使用的区间 \([a,b]\) 中,\(b\) 最大的那个加入 \(S\) 中。(当然你最后还是要满足加入的区间是枚举的 \(|S|=r_s\) 这么多个的)

最后看 \(i\in[s+1,n]\) 的点的 \(r_i\) 是否满足要求即可。

此时时间复杂度 \(\mathcal{O}(n^2\times m\times \log V \times \log m)\)

可以发现,一个很需要优化的空间在于,我们浪费了很多时间去枚举 \(s,r_s\),而我们本质上只需要找到一组合法的解即可,这样是否显得有些冗余呢?

\(\large \mathbf{Claim\ 2}\)

对于最优的 \(S\not= \varnothing\),其一定满足 \(\text{mid} \ge \max _{i\in [1,n]}p_i\ge \max_{i\in I}p_i \ge \max_{i\in[1,n]}p_i-1\)。用人话说就是在 \(I\) 中的点他们的被覆盖次数的最大值和最终的 \(\max p_i\) 最多只会差 \(1\)

我们仍然还是去考虑不符合条件的 \(S\),对其进行调整,即当前 \(\max _{i\in I}p_i < \max _{i\in[1,n]}p_i-1\) 时一直执行以下两种操作。

  • 如果存在一个区间 \([a,b]\in S\) 且其对应的点集 \([a,b]=I\),那么直接删掉 \([a,b]\),可以发现对于 \(\forall i\in I,p_i=p_i+1,\forall i\not \in I,p_i=p_i-1\),差距在减小。
  • 否则假设 \(I\) 中的点对应的是区间 \([l,r]\),考虑在 \(S\) 中找到 \([l,b_1],[a_1,r]\) 这两个区间(可以发现这两个区间至少会分别在 \(S\) 中存在一个),把他们删掉,此时,\(\forall i\in I,p_i=p_i+2\),剩下的 \(p_i\) 再怎么也是在减小,所以差距仍然在减小。

可以发现终止条件要么是 \(S\) 符合条件,要么是 \(S=\varnothing\)

\(\large \mathbf{Algorithm\ 2}\)

回顾一下第一个算法,我们是去枚举的 \(s,r_s\)

我们定义的 \(s\in I\),为了契合我们刚刚的结论,考虑把这个 \(s\) 的枚举加强为 \(I\)\(p_s\) 最大的点,本质上不会造成什么影响。

由于 \(\text{mid} \ge p_s\ge \max p_i-1\),而由于结论 \(0\),我们把 \(\max p_i\) 从他原来的值提升到 \(\text{mid}\) 也是有解的,故我们只需要考虑 \(\text{mid}\ge p_s\ge \text{mid} - 1\) 的情况,此时 \(p_s=q_s+|S|-2\times r_s=q_s-r_s\),所以相应的,\(r_s\) 对应的值也就只有 \(q_s-\text{mid}+\{0,1\}\),也就是说,我们把刚才枚举 \(r_s\) 的那层循环精确到了 \(\mathcal{O}(1)\) 级别。

此时时间复杂度 \(\mathcal{O}(n^2\times \log V \times \log m)\)

那我们可不可以试图去优化 \(s\) 的枚举呢?

\(\large \mathbf{Claim\ 3}\)

对于最优的 \(S\),如果 \(S\not= \varnothing\),其中一定存在一个,满足 \(s\in I,q_s=\max _{i\in [1,n]}q_i\)。也就是说,输入之后被覆盖的最多的点的其中一个,一定会存在于某个最优的 \(S\) 所对应的 \(I\) 中。

其实,这个 \(s\) 不仅取到了 \(q\) 的最大值,他还是 \(I\)\(p\) 最大的节点。

我们从 \(p\) 最大的点 \(s\) 来说明 \(s\) 也取到了 \(q\) 的最大值。

首先有 \(p_s=q_s-r_s\)(这个刚刚在算法二算过一遍了),而 \(p_s\ge \max p_i -1\) 故有 \(q_s\ -r_s \ge \max p_i -1 = \max (q_i+|S|-2\times r_i)-1=\max (q_i+r_s-2\times r_i-1)\)

由于 \(\forall i\not \in I,r_i\le r_s-1\),故有 \(q_s-r_s\ge \max(q_i-r_s+[i\not \in I])-1\)

此时,\(q_s\ge \max(q_i+[i\not \in I])-1\)。故 \(q_s=\max q_i\),从而得证。

\(\large \mathbf{Claim\ 4}\)

对于最优的 \(S\),如果 \(S\not= \varnothing\),那么一定存在一个 \(S\),满足所有的 \(\{s|q_s=\max q_i\}\subseteq I\)

我们有了正向的从 \(I\) 中选择其中 \(q\) 最大的一个必然会存在于最优方案中,那么是不是任意一个最大的都在最优方案中呢?

对于任意的 \(s,q_s=\max q_i\),有 \(p_s=q_s+|S|-2\times r_s\le \text{ans} \le q_s-|S| + 1\)。(根据性质二可得。)

故根据后面的不等关系, \(2\times |S|\le 2\times r_s+1\),由于 \(|S|\ge r_s\),故这里只能取 \(|S|=r_s\)

于是证毕。

\(\large \mathbf{Algorithm\ 3}\)

由于已经证明了 \(q_s\) 最大在最优的 \(I\) 中的任意性,也就是说,我们只需要枚举 \(q_s\) 最大的点中的任意一个,然后再枚举 \(r_s\),而 \(r_s\) 只有两种可能的取值。

时间复杂度来到 \(\mathcal{O}(n\times \log m \times \log V)\),终于是可以通过了。

\(\texttt{Code}\)

posted @ 2024-12-27 17:03  Saltyfish6  阅读(47)  评论(0)    收藏  举报
Document