后缀自动机入门题求助!玄关

学术版

``` #include<iostream> #include<cstdio> #include<cmath> #include<vector> #include<cstring> #define maxn 100005 using namespace std; int n,m; int fa[maxn*4],ch[maxn*4][30],len[maxn*4],tot=1,las=1,tag[maxn*4]; void add_sam(int c){ int q=++tot,p=las;las=q; len[q]=len[p]+1; for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=q; if(!p) fa[q]=1; else{ int nq=ch[p][c]; if(len[nq]==len[p]+1){ fa[q]=nq; return; } int k=++tot; len[k]=len[p]+1; for(int i=0;i<30;i++) ch[k][i]=ch[nq][i]; fa[k]=fa[nq],fa[nq]=fa[q]=k; for(;p&&ch[p][c]==nq;p=fa[p]) ch[p][c]=k; } return; } int head[maxn*4],nex[maxn*4],to[maxn*4],cnt,rec[maxn*4]; int dfn[maxn*4],dfn_num,siz[maxn*4],dfn_pos[maxn*4]; void dfs(int x){ dfn[++dfn_num]=x,siz[x]=1,dfn_pos[x]=dfn_num; for(int i=head[x];i;i=nex[i]){ int y=to[i]; dfs(y); siz[x]+=siz[y]; } return; } int ans1[maxn],ans2[maxn],rec_pre[maxn*4],rec_nex[maxn*4]; struct node{int number,bef;}; vector<vector<node> > v(maxn*4); int tree[maxn*4]; void add(int x,int y){ for(;x<=tot;x+=(x&-x)) tree[x]+=y; return; } int query(int x){ int sum=0; for(;x;x-=(x&-x)) sum+=tree[x]; return sum; } int main(){ //freopen("data.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ int len; scanf("%d",&len); while(len--){ int s; cin>>s; add_sam(s); tag[las]=i; } add_sam(28); scanf("%d",&len); while(len--){ int s; cin>>s; add_sam(s); tag[las]=i; } add_sam(28); } for(int i=1;i<=tot;i++){ nex[++cnt]=head[fa[i]]; head[fa[i]]=cnt; to[cnt]=i; } dfs(1); for(int i=1;i<=m;i++){ int len; scanf("%d",&len); int loc=1,fla=0; while(len--){ int s; cin>>s; if(ch[loc][s]) loc=ch[loc][s]; else fla=1; } if(!fla){ int hea=dfn_pos[loc],tail=dfn_pos[loc]+siz[loc]-1; v[tail].push_back((node){i,hea}); rec_pre[i]=hea,rec_nex[i]=tail; } } for(int i=1;i<=cnt;i++){ int t=dfn[i]; if(tag[t]!=0&&rec[tag[t]]) add(rec[tag[t]],-1); if(tag[t]!=0) rec[tag[t]]=i,add(i,1); for(int j=0;j<v[i].size();j++){ ans1[v[i][j].number]=query(i)-query(v[i][j].bef-1); } } for(int i=1;i<=m;i++) cout<<ans1[i]<<endl; bool vis[maxn*4]; for(int i=1;i<=m;i++){ memset(vis,0,sizeof(vis)); for(int j=rec_pre[i];j<=rec_nex[i];j++){ if(!vis[tag[dfn[j]]]){ ans2[tag[dfn[j]]]++; vis[tag[dfn[j]]]=1; } } } for(int i=1;i<=n;i++) cout<<ans2[i]<<" "; cout<<endl; return 0; } ```
by _lyrics_ @ 2024-04-10 21:41:49


才发现没说题目,题目是[这一道](https://www.luogu.com.cn/problem/P2336),Thanks
by _lyrics_ @ 2024-04-10 22:04:06


|