CF1246F

CJzdc發表於2024-10-03

考慮怎麼較容易地表示 \(\operatorname{dist}(u,v)\)。注意到對於每個點 \(v\)\(\leq 1\) 步能到 \(v\) 的點形成一段區間,記為 \([l_v,r_v]\)。考慮列舉終點 \(x\) 和最短路長度 \(d\),動態維護所有 \(\operatorname{dist}(u,v)\leq d\) 的所有點 \(u\),這些 \(u\) 顯然也是一段區間,記為 \([L,R]\)。答案即為對於每個時刻 \(n-(R-L+1)\) 的和。

可以發現,當 \(d\leftarrow d+1\) 時,區間 \([L,R]\) 會變為 \([\min\limits_{i=L}^Rl_i,\max\limits_{i=L}^Rr_i]\),這就是和 CF1707E 一樣的形式。但是此時還需統計長度和,不能用 CF1707E 的方法直接做。

觀察所有區間 \([l_i,r_i]\) 的性質,事實上 \([L,R]\)\(\min l\) 只和 \(L\)\([L,R]\) 中出現的字元有關,\(\max r\) 同理。於是每次只需要找到第一次出現新的字元的時刻就好了,因為對於每個 \(L\) 和 每個 \(R\),不同的字符集合只有 \(\leq|\Sigma|\) 個,直接預處理跳一步之後的位置,倍增即可。

時間複雜度為 \(O(n|\Sigma|\log n)\),空間可以透過每次統一處字符集大小相同的區間做到 \(n\log n+n|\Sigma|\)

https://codeforces.com/contest/1246/submission/284135674