Count New String
题意:
- 定义字符串函数 (f(S,x,y)(1le xle yle n)),返回一个长度为y-x+1的字符串,第 i 位是 (max_{i=x...x+k-1}S_i)
- 设集合(A = {f(f(S, x_1,y_1),x_2-x_1+1,y_2-x_1+1)|1le x_1 le x_2 le y_2 le y_2 le n})
- 求集合A 的大小
- (Nle 1e5) 字符集大小 <=10
分析:
先放出官方题解
方法一
核心点1比较容易想到,进一步可以观察到他们之间有很大一部分后面是重复的,感性的想到如果倒着插入Trie树,在Trie树上面的节点可能不会很多。具体证明来讲,当前字符 (i), 最近的大于它的字符的位置是 (j (j > i)), 那么在将位置 (i + 1) 的字符插入到Trie树之后,还要把长度 ((j - i)) 的字符串插入到Trie树中。考虑一个 (j_2),再找一个最大的 (j_1) 有 (S_{j_1} ge S_{j_2}),那么([j_1,j_2])这个区间最多利用10次,所以Trie树节点不超过10N。然后就是常规的在Trie树上面建立广义后缀自动机,扫一遍所有节点即可得到本质不同的子串个数
#include<bits/stdc++.h>
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "