Live2D

Solution Set -「LOCAL」冲刺省选 Round XXII

  欸欸欸?以前的 round 编号是不是都多写了一个 X 啊,怎么没人告诉我 qwq。

\(\mathscr{Solution}\)

\(\mathscr{A-}\) 排队

  给定 \(n,m,\{a_m\}\),求前缀为 \(\{a_m\}\) 的所有 \(n\) 阶排列 \(p\) 中,满足 \(\sum_{[i>p_i]}(i-p_i)=\pi(p)\) 的数量。答案模 \((10^9+7)\)

  \(m\le n\le10^5\)


  起码,在开始找规律之前,得动脑子思考一下吧。😅

  显然 \(\sum_{[i>a_i]}(i-a_i)=\sum_{[i<a_i]}(a_i-i)\),考虑后面这个式子的具象意义比较方便:\(a_i\) 放在 \(i\),后面的逆序对数至少是 \(a_i-i\)。我们的目标即是同时让每个下界都被取到,才能获得正确的逆序对数。

  升序考虑值,把值插入到排列的对应位置,可以简单发现:

  • 下界都取到,前缀 \(\max\) 单增;
  • 没有其他逆序对,除前缀 \(\max\) 序列后,排列单增。

  所以,前缀 \(\max\) 序列(位置和值)确定后,排列确定。直接观察前缀 \(\max\),是一段阶梯状的函数,类 Catalan 算一算方案数就行。复杂度 \(\mathcal O(n)\)

\(\mathscr{B}-\) 论文查重

  给定字符串集合 \(\{S_n\}\),序列 \(\{a_m\}\) 以及字符串 \(T\),求 \(T\)\(S=S_{a_1}S_{a_2}\cdots S_{a_m}\) 的 LCS。

  \(n,m,|T|\le2\times10^3\)\(\sum_i|S_i|\le10^6\)


  LCS 的长度不超过 \(|T|\),这个范围显然小于 \(|S|\),所以应该把它记到状态里。令 \(f(i,l)=(x,y)\) 表示 \(T[1:i]\)\(S\) 中取到 \(l\) 长的 LCS 时,至少需要用到 \(S_x\) 的第 \(y\) 个字符。对每个 \(S_i\) 预处理一个序列自动机就能转移了。如果当前 \(S_x\) 转移不了就在 \(\{a_m\}\) 上二分下一个有这一字符的串。复杂度 \(\mathcal O(|T|^2|\Sigma|\log m+|\Sigma|\sum_i|S_i|)\),实现得好 \(\log\) 应该可以丢掉。

\(\mathscr{C}-\) 烽火戏诸侯

  给定 \(\{a_n\}\),每次选一对 \(a_i+1<a_j\),令 \(a_i\leftarrow a_i+1\)\(a_j\leftarrow a_j-1\)。求最多能操作多少次。

  \(n\le10^5\)


  结论:保持 \(\{a_n\}\) 有序,若能操作某个 \(a_i+1<a_{i+1}\),操作它;否则若能操作某个 \(a_i+1<a_{i+2}\),操作它。欸不是,我代码删个判句就对了,你起码告诉我为什么呀。

  证明留作悬念,我们看看怎么维护。尝试增量法:先通过操作使 \(a_{1..k}\) 变成值连续段,加入 \(a_{k+1}\) 时,形如下图:

现加入 \(H\) 点,操作 \((F,H)\),为了保持值连续,连锁操作 \((E,F),(D,E)\),最后 \(H\) 下降 \(1\) 单位的效果是 \(D\)(升序段末尾)上升 \(1\) 单位,贡献是升序段的长度,并且合并了两个升序段(\(C\) 本来自己是独立的升序段)。所以,这里直接用栈维护升序段起点,BIT 维护序列,均摊只有 \(\mathcal O(n)\) 次点-升序段的整体修改。当 \(H\) 高度不够时,计算得到能够抬升的升序段前缀,修改一下,增加一个升序段,不影响复杂度。

  维护出值连续段后,丢在桶里模拟一下两边往中间操作的过程即可。复杂度 \(\mathcal O(n\log n)\),其实我觉得实现得好 \(\log\) 还是能丢掉。(

posted @ 2022-02-27 13:04  Rainybunny  阅读(90)  评论(0编辑  收藏  举报