CF547E Mike and Friends 后缀自动机+线段树合并
裸题,敲完后没调就过了 ~
code:
#include <bits/stdc++.h> using namespace std; #define ll long long #define lson t[x].ls #define rson t[x].rs #define setIO(s) freopen(s".in","r",stdin) const int N=200006; char str[N]; int tax[N<<1],rk[N<<1]; int n,tot=1,cnt,last,pre[N<<1],ch[N<<1][26],mx[N<<1],rt[N<<1],id[N<<1]; struct node { ll sum; int ls,rs; }t[N*30]; int newnode() { return ++ cnt; } void update(int &x,int l,int r,int p,int v) { if(!x) x=newnode(); t[x].sum+=v; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) update(lson,l,mid,p,v); else update(rson,mid+1,r,p,v); } int merge(int x,int y) { if(!x||!y) return x+y; int now=newnode(); t[now].sum=t[x].sum+t[y].sum; t[now].ls=merge(t[x].ls,t[y].ls); t[now].rs=merge(t[x].rs,t[y].rs); return now; } ll query(int x,int l,int r,int L,int R) { if(l>=L&&r<=R) return t[x].sum; ll re=0; int mid=(l+r)>>1; if(L<=mid) re+=query(lson,l,mid,L,R); if(R>mid) re+=query(rson,mid+1,r,L,R); return re; } void Insert(int c) { if(ch[last][c]) { int p=last,q=ch[last][c]; if(mx[q]==mx[p]+1) last=q; else { int nq=++tot; last=nq; mx[nq]=mx[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); pre[nq]=pre[q],pre[q]=nq; for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq; } } else { int p=last,np=++tot; mx[np]=mx[p]+1,last=np; for(;p&&!ch[p][c];p=pre[p]) ch[p][c]=np; if(!p) pre[np]=1; else { int q=ch[p][c]; if(mx[q]==mx[p]+1) pre[np]=q; else { int nq=++tot; mx[nq]=mx[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); pre[nq]=pre[q],pre[np]=pre[q]=nq; for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq; } } } } void M() { int i,j; for(i=2;i<=tot;++i) ++tax[mx[i]]; for(i=1;i<=tot;++i) tax[i]+=tax[i-1]; for(i=1;i<=tot;++i) rk[tax[mx[i]]--]=i; for(i=tot;i>1;--i) { int u=rk[i]; int ff=pre[u]; rt[ff]=merge(rt[ff],rt[u]); } } int main() { // setIO("input"); int i,j,m; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { scanf("%s",str+1); int len=strlen(str+1); last=1; for(j=1;j<=len;++j) Insert(str[j]-'a'),update(rt[last],1,n,i,1); id[i]=last; } M(); for(i=1;i<=m;++i) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%lld\n",query(rt[id[k]],1,n,l,r)); } return 0; }