Reading

ARC099F Eating Symbols Hard


Fanyi Pu

有一段标号从 −∞ 到 +∞ 的序列 A,初始是 Ai=0。现在有一个人在 0 位置,有一段操作序列 s,依次进行操作。

假设 i 时刻这个人在位置 p,如果 si 是 '+',则将 Ap 加 1,如果是 '-',则减 1;如果是 '<' 则该人左移一格,否则是 '>' 则右移一格。

要求数出 s 的所有连续子串中最终得到的 A 与 s 最终得到相同 A 序列的个数。

数据范围 |s|≤250000。

考虑构造一波类似生成函数的东西 f(x)=∑i=−∞+∞Aixi,另外还有一个指针 g,开始是 g 指向 0 位置,显然初始时 f(x)=0。

我们令 fi(x) 表示 1∼i 这一段子串操作所得到的 f 值,gi 表示 1∼i 操作后的指针位置。考虑在末尾加入一个字符 c,如果 c 是 '+' 或 '-',那显然 {fi(x)=fi−1(x)±xgigi=gi−1,同理如果 c 是 '<' 或 '>',那显然 {fi(x)=fi−1(x)gi=gi−1∓1。

如果要计算 [l,r] 的 f 值,不难发现就是 fr(x)−fl−1(x)xgl−1。

于是我们要算的就是 fn(x)=fr(x)−fl−1(x)xgl−1,考虑随便选一个 x,算出这个多项式的值然后哈希一下即可。

代码

Cite this post

@misc{pu2020oiicpcatcoderarc099d,
  author = {Pu, Fanyi},
  title  = {ARC099F Eating Symbols Hard},
  year   = {2020},
  month  = {3},
  url    = {https://pufanyi.com/blog/oi-icpc/atcoder/arc099-d}
}