i号节点表示的不同串的个数是dis[pre[i]]-dis[i],而这个串出现的次数就是当前节点的right集合大小
于是就有奇怪的转移方程了
然后胡搞乱搞一切水到渠成【玄学吗x
#include<bits/stdc++.h>
#define MAXN 400057
using namespace std; char read_s[MAXN];
struct t1{
int son[MAXN][26],pre[MAXN],dis[MAXN];
int siz[MAXN];
int lst,cnt;
int lth;
int p,np,q,nq;
void insert(int x){
dis[np=++cnt]=dis[p=lst]+1;
lst=np;
siz[np]=1;
for(;p&&!son[p][x];p=pre[p]) son[p][x]=np;
if(!p) return pre[np]=1,void();
q=son[p][x];
if(dis[p]+1==dis[q]) pre[np]=q;
else{
dis[nq=++cnt]=dis[p]+1;
memcpy(son[nq],son[q],sizeof son[q]);
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
for(;p&&son[p][x]==q;p=pre[p]) son[p][x]=nq;
}
}
void build(){
lst=cnt=1;
scanf("%s",read_s);
lth=strlen(read_s);
for(int i=0;i<lth;+&#