【BZOJ3277】串
题面
http://darkbzoj.tk/problem/3277
题解
#include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<set> #define N 100050 #define ri register int using namespace std; int n,k; struct node{ int ff,len; int ch[26]; set<int> s; } t[N<<1]; vector<int> son[N<<1]; struct SAM { int cnt[N<<1]; int last,tot; void init(){ last=tot=1; } int extend(int p,int c,int id) { int np; { np=++tot; t[np].len=t[p].len+1; while (p && !t[p].ch[c]) t[p].ch[c]=np,p=t[p].ff; if (!p) { t[np].ff=1; } else { int q=t[p].ch[c]; if (t[q].len==t[p].len+1) { t[np].ff=q; } else { int nq=++tot; t[nq]=t[q]; t[nq].len=t[p].len+1; t[np].ff=t[q].ff=nq; while (p && t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].ff; } } } t[np].s.insert(id); return np; } void maketree() { for (ri i=1;i<=tot;i++) son[t[i].ff].push_back(i); } void merge(int x) { for (ri i=0,l=son[x].size();i<l;i++) { merge(son[x][i]); set<int> :: iterator it; for (it=t[son[x][i]].s.begin();it!=t[son[x][i]].s.end();++it) t[x].s.insert(*it); } } } sam; string s[N]; int main(){ ios::sync_with_stdio(false); cin>>n>>k; sam.init(); for (ri i=1;i<=n;i++) { cin>>s[i]; int p=1; for (ri j=0,l=s[i].size();j<l;j++) p=sam.extend(p,s[i][j]-'a',i); } sam.maketree(); sam.merge(1); for (ri i=1;i<=n;i++) { int cnt=0;long long ans=0; int now=1; for (ri j=0,l=s[i].size();j<l;j++) { if (t[t[now].ch[s[i][j]-'a']].s.size()>=k) { cnt++; now=t[now].ch[s[i][j]-'a']; ans+=cnt; } else { while (now && t[t[now].ch[s[i][j]-'a']].s.size()<k) now=t[now].ff; if (!now) { cnt=0; now=1; } else { cnt=t[now].len+1; now=t[now].ch[s[i][j]-'a']; ans+=cnt; } } } cout<<ans<<" "; } return 0; }