广义后缀自动机串定位
#include<bits/stdc++.h>
using namespace std;
const int L=3e5+5;
struct yuansu {
int ch[26];
int len,fa,self_ch,val;
yuansu() {
memset(ch,0,sizeof(ch));
len=fa=self_ch=val;
}
} dian[2*L],trie[L];
int cnt=0,lenth,now,head(0),tail(1),q[L],n,lst=1,trie_id_to_SAM_id[L],st[L][21],m,w[L],index_to_trie_id[L];
long long int ans;
string S,T;
void init() {
cin>>n>>m;
cin>>S;
cin>>T;
for(int i=1; i<=n; i++)cin>>w[i];
for(int i=n; i>=1; i--)w[i]+=w[i+1];
now=0;
lenth=n;
for(int j=0; j<n; j++) {
if(!trie[now].ch[S[j]-'a']) {
trie[now].ch[S[j]-'a']=++cnt;
trie[trie[now].ch[S[j]-'a']].self_ch=S[j]-'a';
trie[trie[now].ch[S[j]-'a']].fa=now;
trie[trie[now].ch[S[j]-'a']].len=trie[now].len+1;
}
now=trie[now].ch[S[j]-'a'];
trie[now].val=w[j+1];
}
now=0;
lenth=n;
for(int j=0; j<n; j++) {
if(!trie[now].ch[T[j]-'a']) {
trie[now].ch[T[j]-'a']=++cnt;
trie[trie[now].ch[T[j]-'a']].self_ch=T[j]-'a';
trie[trie[now].ch[T[j]-'a']].fa=now;
trie[trie[now].ch[T[j]-'a']].len=trie[now].len+1;
}
now=trie[now].ch[T[j]-'a'];
index_to_trie_id[j+1]=now;
}
return;
}
void bfs_trie() {
q[0]=0;
while(head!=tail) {
for(int i=0; i<=25; i++) {
if(trie[q[head]].ch[i]) {
q[tail++]=trie[q[head]].ch[i];
}
}
++head;
}
return;
}
void insert(int cha,int nw,int v) {
int np=++cnt,p=lst;
trie_id_to_SAM_id[nw]=np;
dian[np].val=v;
dian[np].len=dian[p].len+1;
for(; p&&!dian[p].ch[cha]; p=dian[p].fa)dian[p].ch[cha]=np;
if(!p) {
dian[np].fa=1;
} else {
int q=dian[p].ch[cha];
if(dian[q].len==dian[p].len+1) {
dian[np].fa=q;
} else {
int nq=++cnt;
dian[nq]=dian[q];
dian[nq].len=dian[p].len+1;
dian[q].fa=dian[np].fa=nq;
for(; p&&dian[p].ch[cha]==q; p=dian[p].fa)dian[p].ch[cha]=nq;
}
}
return;
}
void build_SAM() {
cnt=1;
tail--;
trie_id_to_SAM_id[0]=1;
for(int i=1; i<=tail; i++) {
lst=trie_id_to_SAM_id[trie[q[i]].fa];
insert(trie[q[i]].self_ch,q[i],trie[q[i]].val);
}
return;
}
struct item {
int nx,to;
item() {
nx=to=0;
}
} bian[L];
int ls[L],cnt_tree;
void add(int x,int y) {
bian[++cnt_tree].nx=ls[x];
bian[cnt_tree].to=y;
ls[x]=cnt_tree;
}
void dfs(int now,int fa) {
for(int i=ls[now]; i; i=bian[i].nx) {
if(bian[i].to!=fa) {
dfs(bian[i].to,now);
dian[now].val+=dian[bian[i].to].val;
}
}
return;
}
int main() {
init();
bfs_trie();
build_SAM();
for(int i=1; i<=cnt; i++)add(dian[i].fa,i),add(i,dian[i].fa);
dfs(0,-1);
for(int i=1; i<=cnt; i++)st[0][i]=dian[i].fa;
for(int i=1; i<=20; i++) {
for(int j=1; j<=cnt; j++) {
st[i][j]=st[i-1][st[i-1][j]];
}
}
for(int i=1; i<=m; i++) {
int l,r;
cin>>l>>r;
int now(trie_id_to_SAM_id[index_to_trie_id[r]]);
for(int j=20; j>=0; j--) {
if(dian[st[j][now]].len>=r-l+1)now=st[j][now];
}
cout<<dian[now].val<<'\n';
}
return 0;
}
/*
1
ab
*/