Loading

省选集训day6

省选集训day6

考试

T1

我们首先用 \(O(n)\) 的复杂度去预处理所有点到 \(s_1,s_2,t_1,t_2\) 的最短路,然后我们用 \(O(n^2)\) 的复杂度去枚举公共部分的两个端点,显然,公共部分是连续的一段。如果我们直接在上面二分导数的话,时间复杂度是 \(O(n^2\log n)\) ,不可接受,但是我们发现,对于一个确定的公共部分长度 \(a\) 来说,最优解一定满足非公共部分是最短的,所以我们可以在 \(n^2\) 枚举的时候处理出对于所有的长度 \(a\),它最小短的非公共部分的 \(b\) 长度是多少。然后我们对于每一个长度(显然长度最大是 \(n\) ),去二分他的导数,其实也可以三分来做,因为这个函数(时间是因变量,给公共部分的前是自变量)是一个凹函数。这个题就做完了,复杂度 \(O(n^2+n\log n)\)

T2

\(n=R-L+1\)\(O(n^3)\) 的 dp 比较显然,一共有 \(O(n^2)\) 个状态:
\(L(x, r)\):显示屏上的数字是 \(x\),现在还没区分开的区间是 \([x+1,r]\)
\(R(l, x)\):显示屏上的数字是 \(x\),现在还没区分开的区间是 \([l, x-1]\)
然后 \(O(n)\) 枚举接下来猜的数字,算算距离就可以了。现在我们要加速这个过程,观察到最多操作的次数也不会很多,其实最多 45 次,新的状态是:
\(range\_left(c,x) = min\{l : R(l,x) \le c\}\)
\(range\_right(c,x) = max\{r : L(x,r) \le c\}\)
\(dist(a,b)\) 表示从 \(a\) 变到 \(b\) 最少要几步;现在让我们来算算 \(range\_right(c,*)\),假设所有小于 \(c\) 的状态我们都知道了。\(range\_right(c,x) \ge y\) 成立的条件是存在一个 \(m\) 满足 \(range\_left(c-dist(x,m)-1,m) \le x+1\) 并且 \(range\_right(c-dist(x,m)-1,m) \ge y\),其中 \(m\) 是下一步要猜的数字;我们在逻辑上用如下方法把 \(m\) 变成 \(x\):把 \(m\) 中的若干位置变成 ?,然后把 ? 变成 \(x\) 中对应的数字。比如说 31337->3??3?->35932。我们把 \(11^5\) 个状态(5个位置,每个位置可以是 0…9 或 ?)映射到 int,并且引入辅助数组 \(D\)。现在考虑 \(x\),对于每个满足 \(range\_left(c-d-1,m)=x+1\) 的可能的距离 \(d\in[1,5]\) 和数字 \(m\in[1,100000)\),考虑 \(C(5,d)\) 种把 \(m\) 中的 \(d\) 个数字变成 ? 的方式,对于每个变出来的串 \(w\),更新 \(D(w)=max(D(w),range\_right(c-d-1,m))\);那么 \(range\_right(c,x)\) 就是所有可以从 \(x\) 变出来的 \(w\)\(D(w)\) 的最大值。
如上方式,\(range\_right\) 可以用 \(45*(5*10^5log(5*10^5)+10^5*32+11^5)\) 的复杂度算出来,\(range\_left\) 也可以用类似方法求。

T3

枚举平行于 \(y\) 轴和 \(z\) 轴的平面(下称平面 \(x\))的位置。和平面 \(x\) 有交的矩形就不用考虑了,和它无交的矩形就必须和平面 \(y\) 和平面 \(z\) 之一有交。平面 \(x\) 在移动的过程中,即平面 \(x\)\(x\) 坐标在从 -inf 变化到 inf 的过程中,每个矩形和平面 \(x\) 有交的时间是连续的一段。在这段时间外,这个矩形必须和平面 \(y\) 或平面 \(z\) 有交,即 \(ymin\le y\le ymax ~||~ zmin\le z\le zmax\),其中 \(ymin\) 为矩形 \(y\) 坐标最小值,\(ymax\) 为矩形 \(y\) 坐标最大值,\(zmin\)\(zmax\) 类似,\(y\) 为平面 \(y\)\(y\) 坐标,\(z\) 为平面 \(z\)\(z\) 坐标。画在 \(x\) 平面上,就是 \(y\) 平面在 \(x\) 平面上的投影(一条平行于 \(y\) 轴的直线)和 \(z\) 平面在 \(x\) 平面上的投影(一条平行于 \(z\) 轴的直线)的交必须在以矩形为中心的红十字形状内。也就是二维版的本问题。

在二维版的本问题中,要判断的其实是每个矩形对应的红十字形状的交是否为空。我们取红十字形状的补集,即左上,右下,左下,右上 4 个不封闭矩形区域。所有矩形的左上区域的并构成了左上的一条轮廓线,其它 3 个角类似,这 4 条轮廓线外的区域即为所有红十字形状的交。如果要判断交是否为空,可以先将 \(y\)\(z\) 坐标的范围限制为 \([-M,M]\)\(M\) 为本题坐标范围),为每个 \(y\) 坐标计算该 \(y\) 坐标上(上=on, 不是above)有多少 \(z\) 坐标位于轮廓线外。对于一个 \(y\) 坐标,在这个 \(y\) 坐标上的 \(z\) 坐标其实有两个下界和两个上界,分别由左上左下右上右下轮廓提供,下界取较大的生效,上界取较小的生效。

在三维版本的问题中,我们要维护上述 4 条轮廓线,同时维护每个 \(y\) 坐标上有多少 \(z\) 坐标位于轮廓线外。我们将所有 \(y\) 坐标按照 \(z\) 坐标的下界和上界由谁提供分为4类(下界可能由左上或者左下轮廓提供,上界则由右上或者右下轮廓提供)。每一类用一棵线段树维护上下界的差。为了方便每一类的线段树都包含每个 \(y\) 坐标。线段树支持查询是否有大于 0 的元素。当轮廓线修改时,每段修改可用线段树区间加操作实现(等下会讲有多少修改)。由于轮廓线都是单调的,肯定 \(y\) 坐标较大的部分由左上提供下界,较小的部分由左下提供。如果我们能维护一个轮廓线端点的 set,则可以在 set 上二分出左上和左下轮廓相交的位置。右侧类似。这样我们就得到了每一类的 \(y\) 坐标区间。在区间上,在对应类别的线段树里查询是否有非 0 位置即可。

最后是轮廓线端点的 set 维护。一个点在轮廓线上出现或消失的事件只能有常数个:它自己的长方体被平面 \(x\) 扫过的开始和结束是两个事件。它可能被别的轮廓线端点挡住,仅在挡住它的轮廓线端点消失时能露出来。所有挡住它的轮廓线都消失的 \(y\) 坐标的集合是一个区间(因为每个轮廓线端点消失的时间都是个区间,取这些区间的交),这个区间也只能生成 2 个事件。所以一个点在轮廓线上出现或消失的事件只能有常数个。我们只要把这些事件处理出来,到对应的时间在 set 中加入或删除对应端点即可。加入和删除的时候要更新 4 棵线段树。

杂题选讲

1

给出 \(n\) 个数 \(a_i\) 的集合,要求这个集合两个不想交的非空子集,使他们的和相等。\(n\le 10^5,a_i\le10^5\)

不难发现,前 \(22\) 个元素组成的子集是 \(2^{22}\),而这些子集元素和是大于等于 \(10^{5}\times 22\),( \(2^{22}>10^5\times 22\) ),后者是权值范围,前者是数据范围。根据鸽巢原理,不难发现其中肯定有和相等的两个子集,那么为了保证他们不相交,我们可以去掉他们交的部分,这样两个集合就相等了。注意空集的判断。

2

一个长度为 \(n\) 的序列,每一轮位置 \(i\) 会变成 \(a_{i-1},a_i,a_{i+1}\) 的中位数,请问过几轮以后数组会不变。\(n\le 10^6\)

离散化。我们不妨枚举一个 \(x\),然后把所有小于 \(x\) 的数弄为 \(0\) ,所有大于 \(x\) 的数弄为 \(1\),连续的一段 \(1,0\) 是不动的。只有 \(01010101\) 这样的串才会变,且是有规律的,我们可以维护一个数据结构,比如说线段树来维护这样的最长的串。

在枚举 \(x\) 的过程中,我们求上述这个 \(01\) 串的最大值。并且,在我们把这个东西离散化之后,每次令 \(x+1\) 时,总只有常数个 \(0,1\) 发生变化,所以这个题就做完了,用线段树维护一下。

3

一个 \(n\) 个点 \(m\) 条边的有向图,要求从 \(s\) 走到 \(m\),再从 \(m\) 走到 \(t\) ,重复的路只算一次。

我们设 \(f_{i,j}\) 表示从 \(i\)\(m\) 再到 \(j\) 的最优解,这里不处理有公共部分的情况。

然后我们在 dij 时这样转移 \(f_{i,j}=f_{j,i}+delta\)\(delta\) 就是 \(dis(i,j)\)

4

\(n\) 个物品,权值为 \(a_i\),选出多个物品,使权值小于 \(c\) 且最大。

贪心一组 \(\le c\) 的解,那么正解和贪心出的解 \(y\) 的差值 \(\le 2e4\)
把贪心拿的东西标成负数,其他依然为正数,现在问题变成容量 \(\le c – y\) 的背包(可能是负数)

把正数放上面,把负数放下面,用 \(f_{i,j,k}\) 表示用了上面前 \(i\) 个数,下面前 \(j\) 个数,能不能表达 \(k\)\(abs(k) <= 2e4\)

\(j\) 不用记,用 \(g_{i,k}\) 表示上面用了 \(i\) 个数,为了表达 \(k\),下面最少用多少数

两种转移,第一种看 \(i+1\) 取不取,另一种看 \(g_{i,k}\) 后面哪一个取( \(g_{i,k}+ 1\)\(g_{i-1,k}\)就可以啦)

5

定义\(f_i = i + max(a_1, a_2, …, a_i)\),其中 \(a\) 数组为 \(i\) 的每个数位,给定 \(i\) ,问 \(j\) 步以后是多少?

\(i, j <= 10^{18}\)

\(f_{i,j,k}\) 表示后 \(i\) 位为 \(0000…j\) ,前面那些位置的最大值为 \(k\) 的情况下要走多少步才会往前进位;\(g_{i,j,k}\) 表示进位以后最后一位是什么;

\(f_i\) 可以推到 \(f_{i+1}\) ,直接暴力加就可以;

算答案的时候先算下需要多少位置,然后按位确定回来;

这个题实现有些难度。

6 Mr. Panda and Typewriter(CCPC Final 2019 C)

\(f[i][j]\) 表示我们已经打完了前 \(i\) 个字符,buffer里是最后 \(j\) 个字符时的最小代价;每次我们新打一个字符(操作 \(1\) ),\(j=0\)

转移
\(f[i][j]->f[i+1][0]\)
$f[i][j]->f[k][j] $ \(k\)\((i-j+1, i)\) 下一次出现的地方,中间都用操作 \(1\) 填满
\(f[i][j]->f[i+k][k]\) 如果前面存在 \((i+1,i+k)\),粘贴过来;

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

7 Mr. Panda and SAD(CCPC Final 2019 H)

这个回头得看看翻译,想一想环。

枚举有多少单独的’’A”和’’D…”连起来;
那么我们就知道了有多少’’…SA’’,’’...S’’,’’AD…’’,’’D…’’;
一定是’’…SA’’和’’D…’’、’’...S’’和’’AD…’’分别配对;
算的时候注意环的情况。
’’…SA’’和’’D…’’形成了环;
’’...S’’和’’AD…’’形成了环;
所有东西形成了环;

8 Infimum of Paths(CCPC Final 2019 B)

删掉所有不能到 \(1\) 号点的点;

如果我们知道了从 \(0\) 开始走 \(k\) 步能到哪里的集合,我们很容易能得到 \(k+1\) 步能到哪里的集合;对于每一个点,我们记一下权值最小的路是从哪里来的;

一共走 \(n+1\) 步,如果中间的过程中到了 \(1\) 号点,我们就把它的值记下来;

走完 \(n+1\) 步都是环啦!我们把到每个点的环的值都算出来;

最后比下大小;

注意这个环可以是路径上任意一点的,我们需要预处理所有的点对应的最小环,我们为了处理 \(n+1\) 步,可以在最后一个节点连一个自环。

9 Non-Maximum Suppression(CCPC Final 2019 E)

我们注意到题目中 \(0.3\)\(0.7\)

而这个密度是很小的。所以我们可以维护一个 \(vector\),面积从大到小枚举所有矩阵,看以他为中心的一个九宫格是否与其它在 \(vector\) 中的矩阵有很大的交,因为密度很小,所以复杂度是线性的。

10 Game(EC Final 2019 F)

爬山。

posted @ 2021-06-04 21:29  hyl天梦  阅读(126)  评论(0编辑  收藏  举报