传送门:cf547E
题解
AC自动机+主席树
代码
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define lc k<<1
#define rc k<<1|1
#define pb push_back
using namespace std;
typedef long long ll;
const int N=2e5+10;
int n,m,ed[N],fl[N],ch[N][26],df[N],ot[N],dfn,cnt;
int rt[N],ls[N*25],rs[N*25],cot;ll ss[N*25];
string s[N];vector<int>g[N];
inline void ins(int id)
{
int i,u=0,alp,len;
cin>>s[id];len=s[id].size();
for(i=0;i<len;++i){
alp=s[id][i]-'a';
if(!ch[u][alp]) ch[u][alp]=++cnt;
u=ch[u][alp];
}
ed[id]=u;
}
queue<int>que;
inline void bfs()
{
int i,u,x,y,z;
for(i=0;i<26;++i) if(ch[0][i]) que.push(ch[0][i]);
for(;!que.empty();){
x=que.front();que.pop();y=fl[x];
for(i=0;i<26;++i){
u=ch[y][i];z=ch[x][i];
if(!z) ch[x][i]=u;
else{fl[z]=u;que.push(z);}
}
}
for(i=1;i<=cnt;++i) g[fl[i]].pb(i);
}
void ad(int pre,int &k,int l,int r,int pos)
{
if(k==pre){k=++cot;ls[k]=ls[pre];rs[k]=rs[pre];ss[k]=ss[pre];}
ss[k]++;if(l^r){
if(pos<=mid) ad(ls[pre],ls[k],l,mid,pos);
else ad(rs[pre],rs[k],mid+1,r,pos);
}
}
void dfs(int x)
{df[x]=++dfn;for(int u:g[x]) dfs(u);ot[x]=dfn;}
inline void build(int pre,int &nw,int id)
{
int i,u=0,len=s[id].size();nw=pre;
for(i=0;i<len;++i){
u=ch[u][s[id][i]-'a'];
if(u) ad(pre,nw,1,dfn,df[u]);
}
}
ll ask(int pre,int k,int l,int r,int L,int R)
{
if((!k) || (ss[k]==ss[pre])) return 0;
if(L<=l && r<=R) return ss[k]-ss[pre];
if(R<=mid) return ask(ls[pre],ls[k],l,mid,L,R);
if(L>mid) return ask(rs[pre],rs[k],mid+1,r,L,R);
return ask(ls[pre],ls[k],l,mid,L,R)+ask(rs[pre],rs[k],mid+1,r,L,R);
}
int main(){
int i,x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i) ins(i);
bfs();dfs(0);
for(i=1;i<=n;++i) build(rt[i-1],rt[i],i);
for(;m;--m){
scanf("%d%d%d",&x,&y,&z);
printf("%I64d\n",ask(rt[x-1],rt[y],1,dfn,df[ed[z]],ot[ed[z]]));
}
return 0;
}