Iridescent41's Blog

「I will see your face down here real soon.」

「UOJ」 UOJ Round 做题记录

我是中国 OI 选手。

开头是两套《省选难度》的 UR,明显做不太动,所以后面放了 UER 的一些题。

UR #25

UOJ805 设计草图

找一下合法的判据,首先保证 [l,r] 长度为偶数,考虑对于替换 ? 之后要能够合法需要的条件。
把所有的 ? 变成 (,令 (+1)1,必须保证所有前缀和非负。
把所有的 ? 变成 ),令 )+1(1,必须保证所有后缀和非负。

维护一下单调栈,处理出来每个位置左右最多能够够到的地方,然后需要二维数点。

UOJ806 见贤思齐

首先 ipi 连边,会形成内向基环树,首先考虑最简单的情况,一棵有根树怎么做。
固定根节点的权值不变或者每天都加一,设第 i 个人在第 j 天结束时能力值为 f(i,j),有

(1){f(i,0)=aif(i,j)=max{f(pi,j1)+[f(i,j1)f(pi,j1)]}

下面的性质很强,需要手玩才能拿出来,即是如果存在 j 使得 f(i,j)=f(pi,j)f(i,j)=f(pi,j)+1,那么在之后的每一个时间点来说都会保持这样的关系。
然后定义 g(i,j)=f(i,j+depi)depi,可以得到

(2)g(i,j)=g(pi,j)g(i,j+1)=g(pi,j+1)

证明是

(3)f(i,j+depi)depi=f(pi,j+deppi)deppif(i,j+depi)depi=f(pi,j+depi+1)depi1

意思是,父节点权值会在 j+1 时是当前节点的权值加一。
然后可以用线段树维护 g(i,),是在 g(pi,) 的基础上修改一段前缀得到。
基环树的做法需要一个观察,对于树上最小权值记为 minl,在经过一天之后,minl 一定会增加 1。于是把环上最小的点拎出来,把边断掉,以它为根按树的做法做即可。

然后学了一下 zky 的做法,感觉吊打 std。

对于 f(i,j) 一开始是 ai 或者是 ai+j,分别对于 api 还比 ai 小,apiai 大的情况,即是说一类会先保持一会不动,一类会让它从开始就增加。
而当过了一段时间之后,f(i,j)=f(pi,j1)+1,很好理解,即是说 ipi 中较小的一个追平了权值之后建立的等式。
于是写出来应该是

(4)f(i,j)=max{min{f(pi,j1)+1,ai+j},ai}

理解一下,取到 min{f(pi,j1)+1,ai+j},表明此时的 api>ai,如果是 f(pi,j1)+1 则表明 i 已经追平了这段差距,否则则表明 i 还没有追平。如果取到了 ai 则说明 pi 还没有追平 i
或许是技巧,这几天看到了几次了,把里层的变量拎出来,对于这个式子拎出来 j,令 g(i,j)=f(i,j)j

(5)g(i,j)=max{min{g(pi,j1)+1,ai},aij}

此时维护一个 l=,r=+,每次 l=max{l,ait},r=min{r,ai}。两个指针相遇就是答案。
可以倍增优化。


UR #24

UOJ792 比特跳舞

首先几个部分分很好求,不想多说,感觉时间复杂度是单 log
瞄了一眼最短代码长度为 408b,居然不是巨型数据结构,有点震撼,这个速度莫非是 Θ(n)。😓

从部分分入手想一下。
怎么算从 uv 的简单路径序列的本质不同的子序列个数,考虑每次往长度为 n 的序列后面添加一个数的贡献。

(6)dpn+1=dpn+2napos=an+1dppos1

注意一下边界,dp0=1,dp1=2
如果这个式子的结果是奇数,那么二元组 (u,v) 是合法的。
首先去掉 2n,这一块一定是偶数,去掉不影响整个式子的奇偶性,注意观察,假设目前没有重复的元素出现,那么这个式子的结果一直都是偶数。如果出现了重复的元素,若该元素不在第一位,那么减去的 apos=an+1dppos1 仍然是偶数;若该元素在第一位,那么减去的 apos=an+1dppos1 中存在 dp0 使得整个式子改变了奇偶性。
于是得到现在的做法,我们只关心第一位数字是啥,以及这一位数字在后续的序列中重复出现的位置,重复出现了奇数次后会对答案有贡献。
思考如何快速统计答案,固定起点非常不好做,平凡的想法是转成考察对于当前节点为终点,能造成多大的贡献,记录当前序列中最后一个数字出现次数,那么之前不同奇偶性的位置都能产生贡献,发现这个东西能直接 dfs 一遍解决。

好吧,这个 dfs 可能还是需要写一下具体实现。

UOJ793 比特智慧

全场最高分 5pts,有点震撼。

UOJ794 比特之地

写了 50pts 做法,100pts 需要 link


UER #10

UOJ706 随机薅羊毛

纯推式子?首先把高斯消元的式子写出来,定义 dpi 表示从 i 开始一直抽直到获奖的期望步数,那么有 dpi=(1pi)j=1,jindpjn1+1
s=i=1ndpi,那么 dpi=(1pi)(sdpi)n1+1=(1pi)(sdpi)+n1n1。调整一下 dpi=s(1pi)+n1npi,然后把所有的 dpi 加起来有

(7)s=i=1ndpi=i=1ns(1pi)+n1npi=si=1n1pinpi+(n1)i=1n1npis=(n1)i=1n1npi1i=1n1pinpi

答案是 sn

UOJ707 重构元宇宙

有点困难,靠看 vfleaking 博客了。
我什么时候能学会把距离转内积啊啊啊啊啊啊。
首先确定这个 k 维空间的原点 0,然后对于点 p,q 来说,有如下三个式子

(8)i=1k(xp,ixq,i)2=d2(p,q)i=1kxp,i2=d2(p,0)i=1kxq,i2=d2(q,0)

然后用第一个式子减去后面两个式子

(9)i=1k((xp,ixq,i)2xp,i2xq,i2)=2i=1kxp,ixq,ii=1kxp,ixq,i=12(d2(p,q)d2(p,0)d2(q,0))

然后原问题重新被描述为

(F)p,q{1,,n1}:j=1kxp,jxq,j=Ap,q.

于是首先钦定原点,每次加入一个新的点都有

(10)i=0k1xt,ixi=d2(x,xi)d2(0,x)d2(0,xt)2

Other

UOJ172 论战捆竹竿

有点难,我边看题解边记录一些东西。
首先每次可以在后面添加一个 border,长度增加 |S|border,首先处理出来 border,记 border 集合中每个 border 的长度为 xi,那么需要找在 [0,w|S|] 中,i=1cntaixi 能有多少种取值。
看起来是跑同余最短路。具体过程是将 x 从小到大排,用 x1 作为模数,对于 [0,x1) 中的点建边,i[2,cnt],j[0,x1),从 j(xi+j)modx1 建权值为 xi 的边,disi 的含义是用 [2,cnt]xi 拼出来的最小的在模 x1 的意义下等于 i 的数。
然后复杂度是 Θ(n2logn) 的,考虑用性质优化。

对于任意一个字符串,它的 border 长度一定会构成 Θ(nlogn) 个等差数列

可以递归证明,proof

然后拎出来每一个等差数列,假设首项为 x,公差为 d,长度为 len
考虑我只有这一个等差数列该怎么去做?观察到会连出来环,一共有 gcd(d,x) 个,并且每个环都是独立的。
那如何在环上更新呢?首先环的起始位置是不会被更新到的,相邻的点之间的边长一定为 d,那现在来维护一个单调队列,里面只用放下标距离当前点在 len 以内的点,对于环上 a 来更新 b 之间的代价为 disa+d(posbposa),于是用 disaposa 作为关键字比较即可。

剩下的问题是在不同模数之间切换,假设先前的模数为 las,现在模数为 now,于是再用 x 更新 (x+las)modnow 即可。

复杂度降为 Θ(nlogn)