#include
using namespace std;
#define in Read()
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=5e5+10;
int n;
int trie[NNN][26],sz;
char s[100];
int mark[NNN];
inline void update(){
int p=0,len=strlen(s+1);
for(int i=1;i<=len;++i){
int c=s[i]-'a';
if(!trie[p][c]) trie[p][c]=++sz;
p=trie[p][c];
}
++mark[p];
}
inline int query(){
int p=0,len=strlen(s+1);
for(int i=1;i<=len;++i){
int c=s[i]-'a';
if(!trie[p][c]) return 0;
p=trie[p][c];
}
++mark[p];
return mark[p]-1;
}
int main(){
n=in;
for(int i=1;i<=n;++i){
scanf("%s",s+1);
update();
}
n=in;
for(int i=1;i<=n;++i){
scanf("%s",s+1);
int val=query();
if(val==1)puts("OK");
if(val> 1)puts("REPEAT");
if(!val )puts("WRONG");
}
return 0;
}
#include
#define in Read()
using namespace std;
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=1e6+10;
int n;
char s[NNN];
int trie[NNN][26],sz;
int val[NNN],fail[NNN],last[NNN];
inline void update(){
int p=0,len=strlen(s+1);
for(int i=1;i<=len;++i){
int c=s[i]-'a';
if(!trie[p][c]) trie[p][c]=++sz;
p=trie[p][c];
}
++val[p];
}
inline void get_fail(){
queue<int>q;
int p=0;
for(int i=0;i<26;++i){
p=trie[0][i];
if(!p)continue;
fail[p]=last[p]=0;
q.push(p);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;++i){
p=trie[u][i];//j+1
if(!p){
trie[u][i]=trie[fail[u]][i];//连成一片
continue;
}
q.push(p);
int v=fail[u];//nxt[j+1]
while(v&&!trie[v][i]) v=fail[v];//while(j&&t[i+1](字符串间kmp就看存不存在)!=t[j+1]) j=nxt[j];
fail[p]=trie[v][i];//nxt[i]=j(++j)
last[p]=val[fail[p]]?fail[p]:last[fail[p]];//最大后缀
}
}
}
inline int query(){
int p=0,len=strlen(s+1);
int ans=0;
for(int i=1;i<=len;++i){
int c=s[i]-'a';
p=trie[p][c];
int tmp=0;
if(val[p])
tmp=p;
else if(last[p])
tmp=last[p];
while(tmp){
ans+=val[tmp];
val[tmp]=0;
tmp=last[tmp];
}
}
return ans;
}
int main(){
n=in;
for(int i=1;i<=n;++i){
scanf("%s",s+1);
update();
}
get_fail();
scanf("%s",s+1);
printf("%d",query());
return 0;
}
#include
#define in Read()
#define int long long
using namespace std;
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
int n;
const int NNN=1e6+10;
char s[200][100],t[NNN];
int sz;
struct ACAM{
int id,fail,last;
int son[26];
}ch[NNN];
struct Ans{
int id,cnt;
friend inline bool operator < (const Ans u,const Ans v){
if(u.cnt!=v.cnt) return u.cnt>v.cnt;
return u.id<v.id;
}
}ans[NNN];
inline void Clear(int x){
memset(ch[x].son,0,sizeof(ch[x].son));
ch[x].id=ch[x].fail=ch[x].last=0;
}
inline void update(int x){
int p=0,len=strlen(s[x]+1);
for(int i=1;i<=len;++i){
int c=s[x][i]-'a';
if(!ch[p].son[c]) ch[p].son[c]=++sz,Clear(sz);
p=ch[p].son[c];
}
ch[p].id=x;
}
inline void get_fail(){
queue<int>q;
int p=0;
for(int i=0;i<26;++i){
p=ch[0].son[i];
if(!p) continue;
q.push(p);
ch[p].last=ch[p].fail=0;
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;++i){
p=ch[u].son[i];
if(!p){
ch[u].son[i]=ch[ch[u].fail].son[i];
continue;
}
q.push(p);
int v=ch[u].fail;
while(v&&!ch[v].son[i]) v=ch[v].fail;
ch[p].fail=ch[v].son[i];
ch[p].last=ch[ch[p].fail].id?ch[p].fail:ch[ch[p].fail].last;
}
}
}
inline void query(){
int p=0,len=strlen(t+1);
for(int i=1;i<=len;++i){
int c=t[i]-'a';
p=ch[p].son[c];
int tmp=0;
if(ch[p].id) tmp=p;
else if(ch[p].last) tmp=ch[p].last;
while(tmp){
ans[ch[tmp].id].cnt+=1;
tmp=ch[tmp].last;
}
}
}
inline void work(){
for(int i=1;i<=n;++i){
scanf("%s",s[i]+1);
update(i);
ans[i].cnt=0;
ans[i].id=i;
}
get_fail();
scanf("%s",t+1);
query();
sort(ans+1,ans+n+1);
printf("%lld\n",ans[1].cnt);
if(ans[1].cnt){
printf("%s\n",s[ans[1].id]+1);
for(int i=2;i<=n;++i){
if(ans[i-1].cnt^ans[i].cnt) break;
printf("%s\n",s[ans[i].id]+1);
}
}
}
signed main(){
while(true){
n=in;
if(!n)break;
for(int i=1;i<=n;++i)ans[i].id=i;
sz=0;
Clear(0);
work();
}
return 0;
}
注意判重
#include
#define in Read()
#define int long long
using namespace std;
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=5e5+10;
char t[NNN],s[NNN*10];
struct Trie{
int son[26];
int fail,last;
int id;
}ch[NNN];
int sz,ans[NNN],n;
int same[NNN];
inline void update(int x){
int p=0,len=strlen(t+1);
for(int i=1;i<=len;++i){
int c=t[i]-'a';
if(!ch[p].son[c]) ch[p].son[c]=++sz;
p=ch[p].son[c];
}
if(!ch[p].id) ch[p].id=x;
else same[x]=ch[p].id;
}
inline void get_fail(){
queue<int>q;
int p=0;
for(int i=0;i<26;++i){
p=ch[0].son[i];
if(!p) continue;
q.push(p);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;++i){
p=ch[u].son[i];
if(!p){
ch[u].son[i]=ch[ch[u].fail].son[i];
continue;
}
q.push(p);
int v=ch[u].fail;
while(v&&!ch[v].son[i]) v=ch[v].fail;
ch[p].fail=ch[v].son[i];
ch[p].last=ch[ch[p].fail].id?ch[p].fail:ch[ch[p].fail].last;
}
}
}
inline void query(){
int p=0,len=strlen(s+1);
for(int i=1;i<=len;++i){
int c=s[i]-'a';
p=ch[p].son[c];
int tmp=0;
if(ch[p].id) tmp=p;
else if(ch[p].last) tmp=ch[p].last;
while(tmp){
++ans[ch[tmp].id];
tmp=ch[tmp].last;
}
}
}
signed main(){
n=in;
for(int i=1;i<=n;++i){
scanf("%s",t+1);
update(i);
}
get_fail();
scanf("%s",s+1);
query();
for(int i=1;i<=n;++i){
if(same[i]) printf("%lld\n",ans[same[i]]);
else printf("%d\n",ans[i]);
}
return 0;
}
#include
#define in Read()
using namespace std;
inline int in{
int i=0,f=1;char ch;
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')ch=getchar(),f=-1;
while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=2e5+10;
char t[NNN],s[NNN*10];
struct Trie{
int son[26];
int fail,into,ans,val;
}ch[NNN];
int sz,m[NNN],n;
//m:记录单词结束点的编号
inline void update(int x){
int p=0,len=strlen(t+1);
for(int i=1;i<=len;++i){
int c=t[i]-'a';
if(!ch[p].son[c]) ch[p].son[c]=++sz;
p=ch[p].son[c];
}
++ch[p].val;
m[x]=p;
}
inline void get_fail(){
queue<int>q;
int p=0;
for(int i=0;i<26;++i){
p=ch[0].son[i];
if(!p) continue;
q.push(p);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;++i){
p=ch[u].son[i];
if(!p){
ch[u].son[i]=ch[ch[u].fail].son[i];
continue;
}
q.push(p);
int v=ch[u].fail;
while(v&&!ch[v].son[i]) v=ch[v].fail;
if(ch[v].son[i]!=p){
ch[p].fail=ch[v].son[i];
++ch[ch[v].son[i]].into;
}
}
}
}
inline void query(){
int p=0,len=strlen(s+1);
for(int i=1;i<=len;++i){
int c=s[i]-'a';
while(p&&!ch[p].son[c]) p=ch[p].fail;//一跳到底,后面的点只与最上面的点有关,可以根据它统计
p=ch[p].son[c];
if(!p)continue;//就是把tmp那很多步变成了一步
++ch[p].ans;
}
}
int main(){
n=in;
for(int i=1;i<=n;++i){
scanf("%s",t+1);
update(i);
}
get_fail();
scanf("%s",s+1);
query();
queue<int>q;
for(int i=1;i<=sz;++i)
if(!ch[i].into&&ch[i].fail)
q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
ch[ch[u].fail].ans+=ch[u].ans;
--ch[ch[u].fail].into;
if(!ch[ch[u].fail].into)
q.push(ch[u].fail);
}
for(int i=1;i<=n;++i)
printf("%d\n",ch[m[i]].ans);
return 0;
}