因为 f 只需要判是否等于,开局先对所有二元组 f 哈希。看到前后缀匹配,可以使用 Trie。在 Trie 上,x 是 y 的前缀相当于 y 对应的节点在 x 对应的节点子树内,如果对字符串按其在 Trie 中对应点子树内的 dfs 序区间标号,可以表示成 lx≤ly≤rx。那么分别对前面定义的所有 L(a,b),L(s,t) 和 R(a,b),R(s,t) 这样标号,就变成了普通的三维偏序且一维限制是等号的问题,可以用动态开点线段树维护每种 f,O(nlogn) 解决。但其实我们如果不对 R 显式标号,把动态开点线段树换成对 R 建 n 棵 f 值不同的动态开点 Trie,在扫描线每次查询时统计从第 f 棵动态开点 Trie 的根到查询的 R(s,t) 对应节点路径上的点的贡献,这部分除去离散化就可以做到线性(实际上也可以上 trie 求 f 的 dfs 序去掉离散化的 log 并且摆脱哈希,但是没啥必要)。