抄来的代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 5050
struct Node
{
int step;
Node *pre,*nxt[26];
void clear()
{
step=0;
pre=NULL;
memset(nxt,NULL,sizeof(nxt));
}
int calc()
{
if(pre==NULL) return 0;
return step-pre->step;
}
}*root,*last;
Node pool[N*2],*cur;
void init()
{
cur=pool;
root=last=cur++;
root->clear();
}
int tot;
void extend(int w)
{
Node *np=cur++,*p=last;
np->clear();
np->step=p->step+1;
while(p&&!p->nxt[w])
p->nxt[w]=np,p=p->pre;
if(p==NULL)
{
np->pre=root;
tot+=np->calc();
}
else
{
Node *q=p->nxt[w];
if(q->step==p->step+1)
{
np->pre=q;
tot+=np->calc(); // q点的值已经算过
}
else // q->step!=p->step+1,构造出一个等于p->step+1的
{
Node *nq=cur++;
tot-=p->calc()+q->calc();
memcpy(nq->nxt,q->nxt,sizeof(q->nxt));
nq->pre=q->pre;
nq->step=p->step+1;
np->pre=q->pre=nq;
tot+=p->calc()+q->calc()+np->calc()+nq->calc();
while(p&&p->nxt[w]==q)
p->nxt[w]=nq,p=p->pre;
}
}
last=np;
}
char str[N];
int ans[N][N];
int main ()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%s",str);
int n=strlen(str);
for(int i=0;i<n;++i)
{
init();
tot=0;
for(int j=i;j<n;++j)
{
extend(str[j]-'a');
ans[i][j]=tot;
}
}
int Q,l,r;scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&l,&r);
l--,r--;
printf("%d\n",ans[l][r]);
}
}
return 0;
}