0%

一类序列上的最短路问题-倍增

CF1246F Cursor Distance

考虑对于每一个i,求出至多走k步就能够到达它的位置所构成的区间[Li,k,Ri,k]。我们只要对每个i分别求出kLi,k,kRi,k就能得到答案。

最短路不一定是单向的(比如对于baaaaac,从b走到最后一个a),所以L,R可能不独立,不能直接倍增计算L,R的和。

进一步观察,Ri,k+2的取值与[Li,k+1,Li,k)中的位置有关的必要条件是[Li,k+1,Ri,k+1]的字符集大于[Li,k,Ri,k]的字符集;如果[Li,k+1,Ri,k+1],[Li,k,Ri,k]字符集相同,则Ri,k+2就只与Ri,k+1[Li,k,Ri,k]的字符集大小有关。

对于每个i,当k0取到+的时候,[Li,k,Ri,k]的字符集大小只会变化|Σ|次(|Σ|表示字符集大小)。故而,我们可以枚举当前这些区间的字符集大小,这时候L,R是独立的,可以直接倍增求出它们的和。

实现细节上,在最外层枚举区间的字符集大小t,然后对每个位置i处理出fli——表示当L为某个满足[L,i]字符集大小为t的位置,R=i的时候,跳一步能够把R扩展到哪里;以及类似定义的fri。预处理出fli,fri倍增的结果。然后对每个i从大到小枚举j,然后看它现在的区间端点扩展2j次以后,区间内是否仍然只有t种字符。

Code


LOJ6435 「PKUSC2018」星际穿越

参考这篇blog

fi,k为从i出发,走k步能够到达的最靠左的点。则有fi,k+1<fi,k

显然fi,1=li

然后是fi,2=minjli{lj}

  • 对于j[li,i)i可以在第一步走到j
  • 对于j>i,如果lji我们可以选择在第一步走到j,否则lj>ilj一定不会被minxli{lx}取到。

对于fi,k(k>2),有fi,k=minj[fi,k1,fi,k2){lj}=minj[fi,k1,i){lj}。由于显然fi,k<fi,2minji{lj}(k>2),所以也可以写作fi,k=minj[fi,k1,n]{lj}。这个式子中fi,k的取值与i无关而只与fi,k1有关,所以可以倍增求出k=2j时的fi,kx[1,k]fi,x

实现上,可以强制先走k=1的第一步fi,1=li,这样的话之后的每一步的转移都满足fi,k=minjfi,k1{lj}

Code