UOJ Logo zhoukangyang的博客

博客

UOJ NOI Round #8 Day2 题解

2024-07-14 14:27:00 By zhoukangyang

兵棋

idea,solution,data,std by zhoukangyang

这题有很多做法,欢迎大家在评论区交流。

考虑设 ti 表示 i 被删除的时间。

考虑从前往后依次确定 ti。如果 i 时刻在 ti 时刻被删掉,那么 i 前面的第一个 tit 上的字符一定和 i 不同。而 ti 是满足条件的值中最小的一个。

所以可以考虑对于每个 j 记录 i 前面第一个(下标最大的一个)满足 tposjspos

考虑记录该字符串。初始状态就是整个字符串均为 s1

加入位置 i 的时候,修改即为在字符串中找到第一个 si 的字符 p,将其修改为 sp。如果找不到则说明该位置不会被删除。

直接用动态规划维护是 O(n2k) 的。

注意到我们其实只关心字符串中 1 的个数!这样就能做到 O(nk) 了。

思考题:如果 s1 也会被删除该怎么做?(这题也能做到 O(nk)。)

难度查找

idea,solution,data,std by zhoukangyang

致歉

本来这题是 n×n 矩阵找第 n 小,只允许比较,要求次数 O(n),放 Day2T3 的。

但是后来因为常数太大,卡不掉暴力,就改成了现在这个版本。

结果这题之前在一些地方的模拟赛里面出现过了,赛前没有查到一样的题,向大家道歉!!

题解

考虑提取所有偶数列,然后求出其中第 (kn)/2 小值。我们发现最后的答案一定大于等于这个值,所以前 k 小的元素中我们已经确定出了 (kn)/2×2 个了,还差 n 个。

现在我们只需要接下来再取出 n 个元素即可。这个可以把每行第一个没被选的元素丢到 priority_queue 实现。

行列交替地做,操作次数是 T(n,m)=T(m,n/2)+2n,有 T(n,n)=6n,还不能通过(然而数据较弱,部分选手直接实现了这个算法也通过了)。

我们发现如果 (x1,y)(x,y1) 还没被选进前 k 小,(x,y) 就暂时不会被选。事实上,加上这个优化操作次数就是 5n 的了。

我们证明从 T(n/2,n/2) 的答案推到 T(n,n) 的过程中我们最多只会问 2.5n 次。

证明:考虑 T(n/2,n)T(n,n) 的过程。设第 i 行刚开始去了 ai 个元素(ai 是偶数),最终取了 bi 个元素,那么最终我们会问 n+|{bi}| 次。在 T(n/2,n/2) 中,我们询问了 n/2+|{ai}| 次。;

我们先假装总询问次数是 3n/2+n+|{ai}| 次,接下来观察我们会在什么情况下少问一些。

在做 T(n/2,n) 时,如果 aiai1,那么 (i,ai+2) 一定被问过了。

此时,如果 aibi,那么我们就利用上了 (i,ai+2) 的信息,询问次数 1;而如果 ai=bi,那么 bi 中一定不会出现 ai+1 这个数,询问次数 1

综上,我们一定少询问了 |{ai}| 次,也就是说我们只会询问 5n/2 次。所以总询问次数不会超过 T(n,n)=T(n/2,n/2)+5n/2,即 T(n,n)=5n

大海的深度

idea,solution,data,std by Kubic

O(nlog2n)

分治。处理所有跨过分治点的贡献。只需 O(logn) 代价即可转化到原问题。

离线,扫描值域。令当前扫描到 x。对于每个 i,维护 pi 表示第 i 时刻分治中心左边距离中心最近的 x 的数的距离,qi 表示右边的距离。

x 增大时对 p,q 的修改均为区间取 min,用 segbeats 维护即可。

还需要维护每个时刻的答案 wi。第 i 时刻 minx 的区间数量即为 pi×qi。因此 x 增大时,需要令 wiwi+pi×qi

每个 i 处维护四维向量 (pi,qi,pi×qi,wi),用矩阵表示修改即可。时间复杂度为 O(nlogn)

加上外层分治,总时间复杂度为 O(nlog2n)

O(nn)

可以把要求的东西转化为 i=1n(sufii)(iprei)ai

其中 prei 表示 i 前面第一个 <ai 的位置,sufi 表示 i 后面第一个 ai 的位置。

考虑询问分块,将 B 个询问分入同一个块中。

在进入每个块之前先将这个块中所涉及到的 B 个位置设为 +,然后计算 presuf

此时序列被这 B 个位置分为了 O(B) 段。

对于一个询问,我们分析填上这 B 个位置的数对 presuf 的影响。只考虑 presuf 的分析是类似的。

可能有一些 pre 会变为这 B 个位置之一。每个段内只有所有非严格前缀最小值的 pre 可能改变。

我们用类似于求 pre 的过程,对这 B 个位置以及每个段内的最小值做单调栈。

到达一个段时,我们可以用当前的单调栈刻画出这个段中所有数的 pre 的变化情况:对于一个当前段中的前缀最小值 ai,我们找到单调栈中第一个 <ai 的数 at。如果 tB 个位置之一,那么 prei 会变为 t,否则 prei 不变。

于是我们可以把一次询问转化为在序列上的 O(B2) 次询问,每次询问一个段中有多少个 w 的数。

这样做的时间复杂度为 O(n2B+nB2),取 B=n13 可以得到 O(n53) 的时间复杂度。

但我们可以进一步优化,可以发现,单调栈中有很多不变的数,我们可以在单调栈改变的时候将后面的数因为这次改变所产生的贡献全部计算出来。每次询问形如在第 x 个段及之后的所有数中有多少个 w 的数。

因为段只有 O(B) 个,并且询问的 w 也只有 O(B) 种,所以我们可以用在每个段内双指针,并用二维前缀和预处理出每一种可能的询问的答案。

O(B) 个点的贡献容易在过程中同时进行计算,这里不再赘述。

这样做的时间复杂度为 O(n2B+nB),取 B=n12 可以得到 O(nn) 的时间复杂度。

评论

T3 O(Qnlogn) 能过。
评论回复
_LHF_:并且跑得比 std 快。
狗屎题目狗屎比赛狗屎出题人全部去死吧 傻逼oj
反正都要退役了我也来喷一下 T3写了个分块,结果写挂了块长不一样答案还不一样,有一发有40',最后一发F了 这个你们搞题的时候是不是故意不想让选手拿到该拿的分的 ![](https://qoj.ac/images/sticker/budui.gif)
评论回复
LYC_music:这也要喷?油饼吗
Kevin090228:回复 @LYC_music:楼阁你好牛
不知道这群死妈玩意是什么死吗心态搁着出这种垃圾场次
T1思考题 是不是直接假装前面有inf个额外的就行了
评论回复
TOMWT:这个额外的放什么颜色呢
jinhaoxian:回复 @TOMWT:直接和第一个不同色感觉是对的(
我的T1做法可能能做思考题! 我把它转化成括号匹配,然后从右往左dp
https://pekka-l.blog.uoj.ac/blog/9198 D2T2 另解
赛时T1的想法: 不妨串的第一位为 0,则若将串的末尾添加足够多的 0,每次操作就会形如:找到所有 10 的位置,删掉这两个字符。把 0 看做向上的折线,1 看做向下的折线,则 k 次操作就相当于在折线上方形成若干水坑,每个水坑深度 k,被淹没的字符就被删除。于是设 f/gi,j 表示前 i 个字符,距离水面 j 的权值/方案数,可以直接 dp。
Day2T2 我的随机二分是线性的,但是分析下来好像是 15n,没什么用。
T2 6n 的做法被 hacked 了。
D2T2 的暴力做法,复杂度分析应该是 T(n,m)=T(m,n/2)+2m

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。