题目描述
题解
首先把所有的S串都丢到trie树里,建立fail树。
每加进来一个T,把它在AC自动机上暴力匹配,匹配到的每一个点在fail树中到根的路径上出现过的S串end标记的S串都应该+1,也就是说,每一次求出匹配到的每一个点在fail树中到根的路径上出现过的end标记表示的S串,然后取并集,这些S串的答案应该+1.
由于有可能有重复计算,我们需要把所有匹配过的点按照dfs序排序,然后要消除相邻的两个点的lca到根的路径上多加的点的影响。如果是树链修改的话比较麻烦,可以转化为单点修改然后查询子树区间权值和,这样就可以用bit轻松实现了。
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define S 2000005
#define N 100005
#define lg 21
char s[S];
int n,m,opt,x,sz,dfs_clock;
int ch[S][30],fail[S],is_end[N],f[S][lg+1],in[S],out[S],h[S],pt[S],C[S];
int tot,point[S],nxt[S],v[S];
queue <int> q;
void insert(int id)
{
int len=strlen(s),now=0;