【CF235C】Cyclical Quest
作者:互联网
题面
https://www.luogu.org/problem/CF235C
题解
#include<cstdio> #include<cstring> #include<iostream> #include<vector> #define ri register int #define N 1000500 using namespace std; vector<int> son[N<<1]; bool vis[N<<1]; char s[N]; string ss; int L0; struct SAM{ int ff[N<<1],len[N<<1]; int ch[N<<1][26]; int cnt[N<<1]; int las,tot; int stk[N<<1],top; void init() { las=tot=1; } void extend(int c) { int np=++tot,p=las; las=np; len[np]=len[p]+1; while (p && !ch[p][c]) ch[p][c]=np,p=ff[p]; cnt[np]++; if (!p) ff[np]=1; else { int q=ch[p][c]; if (len[q]==len[p]+1) ff[np]=q; else { int nq=++tot; for (ri i=0;i<26;i++) ch[nq][i]=ch[q][i]; ff[nq]=ff[q]; len[nq]=len[p]+1; ff[np]=ff[q]=nq; while (p && ch[p][c]==q) ch[p][c]=nq,p=ff[p]; } } } void maketree() { for (ri i=1;i<=tot;i++) son[ff[i]].push_back(i); } void treedp(int x){ for (ri i=0;i<son[x].size();i++) { treedp(son[x][i]); cnt[x]+=cnt[son[x][i]]; } } long long solve() { long long ret=0; int cc=0,now=1; top=0; for (ri i=0,l=ss.size();i<l-1;i++) { int c=ss[i]-'a'; if (ch[now][c]) { cc++; now=ch[now][c]; if (cc>=L0) { if (!vis[now]) vis[now]=1,ret+=cnt[now],stk[++top]=now; while (now!=1 && len[ff[now]]>=L0-1) now=ff[now]; cc=len[now]; } } else { while (now && !ch[now][c]) now=ff[now]; if (!now) { now=1; cc=0; } else { cc=len[now]+1; now=ch[now][c]; if (cc>=L0) { if (!vis[now]) vis[now]=1,ret+=cnt[now],stk[++top]=now; while (now!=1 && len[ff[now]]>=L0-1) now=ff[now]; cc=len[now]; } } } } for (ri i=top;i>=1;i--) vis[stk[i]]=0; vis[1]=0; return ret; } } sam; int n,m; int stk[N<<4],top; int main(){ sam.init(); scanf("%s",s); for (ri i=0,l=strlen(s);i<l;i++) sam.extend(s[i]-'a'); sam.maketree(); sam.treedp(1); scanf("%d",&n); for (ri i=1;i<=n;i++) { cin>>ss; L0=ss.size(); ss=ss+ss; cout<<sam.solve()<<endl; } }
标签:Cyclical,ss,cc,len,vis,Quest,L0,CF235C,now 来源: https://www.cnblogs.com/shxnb666/p/11279296.html