暴跳next
luogu3375
#include <bits/stdc++.h>
const int N = 1e6 + 30;
int pos;
int lena;
int lenb;
int nx[N];
char a[N];
char b[N];
int main()
{
std::cin >> a>> b;
lena = std::strlen(a);
lenb = std::strlen(b);
for (int i = 1; i < lenb; ++i)
{
while (pos != 0 && b[pos] != b[i])
pos = nx[pos];
if (b[pos] == b[i])
++pos;
nx[i + 1] = pos;
}
pos = 0;
for (int i = 0; i < lena; ++i)
{
while (pos != 0 && b[pos] != a[i])
pos = nx[pos];
if (b[pos] == a[i])
++pos;
if (pos == lenb)
printf ("%d\n", i - lenb + 2);
}
for (int i = 1; i <= lenb; ++i)
printf ("%d ", nx[i]);
printf ("\n");
return 0;
}
tire树上暴跳fail
详细学习请搜索yyb博客,讲的很好
luogu3796
#include <bits/stdc++.h>
const int N = 1000000 + 30;
int n;
int tot;
std::string s, str[N];
struct AC
{
int fail;
int end;
int vis[28];
}a[N];
struct NODE
{
int num;
int tot;
}ans[N];
bool operator <(NODE x, NODE y)
{
if (x.tot != y.tot)
return x.tot > y.tot;
else
return x.num < y.num;
}
inline void init(int num)
{
std::memset(a[num].vis, 0, sizeof(a[num].vis));
a[num].fail = 0;
a[num].end = 0;
}
inline void Insert(int num, std::string strr)
{
int now = 0;
int len = strr.size();
for (int i = 0; i < len; ++i)
{
if (a[now].vis[strr[i] - ‘a‘] == 0)
{
a[now].vis[strr[i] - ‘a‘] = ++tot;
init(tot);
}
now = a[now].vis[strr[i] - ‘a‘];
}
a[now].end = num;
}
inline void Work_Fail()
{
int now = 0;
std::queue < int > q;
for (int i = 0; i < 26; ++i)
{
if (a[now].vis[i] != 0)
{
a[a[now].vis[i]].fail = 0;
q.push(a[now].vis[i]);
}
}
while (!q.empty())
{
now = q.front();
q.pop();
for (int i = 0; i < 26; ++i)
{
if (a[now].vis[i] != 0)
{
a[a[now].vis[i]].fail = a[a[now].fail].vis[i];
q.push(a[now].vis[i]);
}
else
a[now].vis[i] = a[a[now].fail].vis[i];
}
}
}
inline void Work_Ans(std::string strr)
{
int now = 0;
int len = strr.size();
for (int i = 0; i < len; ++i)
{
now = a[now].vis[strr[i] - ‘a‘];
for (int t = now; t != 0; t = a[t].fail)
++ans[a[t].end].tot;
}
}
int main()
{
while (37373737)
{
std::cin >> n;
if (n == 0)
return n;
tot = 0;
init(0);
for (int i = 1; i <= n; ++i)
{
std::cin >> str[i];
ans[i] = (NODE){i, 0};
Insert(i, str[i]);
}
Work_Fail();
std::cin >> s;
Work_Ans(s);
std::sort(&ans[1], &ans[n + 1]);
std::cout << ans[1].tot<< std::endl<< str[ans[1].num]<<std::endl;
for (int i = 2; i <= n; ++i)
if (ans[i].tot == ans[i - 1].tot)
std::cout << str[ans[i].num]<<std::endl;
else break;
}
}
luogu3808
#include <bits/stdc++.h>
const int N = 1000000 + 30;
int n;
int tot;
std::string s;
struct AC
{
int fail, end, vis[28];
}a[N];
inline void Insert(std::string str)
{
int now = 0;
int len = str.size();
for (int i = 0; i < len; ++i)
{
if (a[now].vis[str[i] - ‘a‘] == 0)
a[now].vis[str[i] - ‘a‘] = ++tot;
now = a[now].vis[str[i] - ‘a‘];
}
++a[now].end;
}
inline void Work_Fail()
{
int now = 0;
std::queue < int > q;
for (int i = 0; i < 26; ++i)
{
if (a[now].vis[i] != 0)
{
a[a[now].vis[i]].fail = 0;
q.push(a[now].vis[i]);
}
}
while (!q.empty())
{
now = q.front();
q.pop();
for (int i = 0; i < 26; ++i)
{
if (a[now].vis[i] != 0)
{
a[a[now].vis[i]].fail = a[a[now].fail].vis[i];
q.push(a[now].vis[i]);
}
else
a[now].vis[i] = a[a[now].fail].vis[i];
}
}
}
int Work_Ans(std::string str)
{
int now = 0, ans = 0;
int len = str.size();
for (int i = 0; i < len; ++i)
{
now = a[now].vis[str[i] - ‘a‘];
for (int t = now; t != 0 && a[t].end != -1; t = a[t].fail)
{
ans += a[t].end;
a[t].end = -1;
}
}
return ans;
}
int main()
{
std::cin >> n;
for (int i = 1; i <= n; ++i)
{
std::cin >> s;
Insert(s);
}
Work_Fail();
std::cin >> s;
printf ("%d\n", Work_Ans(s));
return 0;
}
原文:https://www.cnblogs.com/martixx/p/13553618.html