您的位置:首页 > 其它

[hdu2222]ac自动机(模板)

2015-05-02 04:05 281 查看
题意:一个文本串+多个模板串的匹配问题

思路:裸的ac自动机。

#pragma comment(linker, "/STACK:10240000,10240000")

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility>

using namespace std;

#define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)

typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
const int maxn = 3e4 + 7;
const int md = 10007;
const int inf = 1e9 + 7;
const LL inf_L = 1e18 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;

template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; }

int ans;

struct AhoCorasickAutoMata {
const static int SIGMA_SIZE = 26;
const static int maxn = 250007;
int cc;
int ch[maxn][SIGMA_SIZE];
int val[maxn], last[maxn], f[maxn];

void clear() { cc = 0; mem0(val); mem0(ch); mem0(last); mem0(f); }

int idex(char ch) { return ch - 'a'; }

void Insert(char s[]) {
int pos = 0;
for(int i = 0; s[i]; i++) {
int id = idex(s[i]);
if(!ch[pos][id]) ch[pos][id] = ++ cc;
pos = ch[pos][id];
}
val[pos] ++;
}

void print(int j) {
if (j) {
ans += val[j];
val[j] = 0;//为了避免重复计数,需要在统计后置零
print(last[j]);
}
}

void find(char T[]) {
int n = strlen(T);
int j = 0;
rep_up0(i, n) {
int c = idex(T[i]);
j = ch[j][c];
if (val[j]) print(j);
else {
if (last[j]) print(last[j]);
}
}
}

int getFail() {
queue<int> q;
f[0] = 0;
rep_up0(c, SIGMA_SIZE) {
int u = ch[0][c];
if (u) {
f[u] = 0;
q.push(u);
last[u] = 0;
}
}
while (!q.empty()) {
int r = q.front(); q.pop();
rep_up0(c, SIGMA_SIZE) {
int u = ch[r][c];
if (!u) {
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
int v = f[r];
while (v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]]? f[u] : last[f[u]];
}
}
}
};

AhoCorasickAutoMata ac;
char str[55];
char s[1000007];

int main() {
//freopen("in.txt", "r", stdin);
int T, n;
cin >> T;
while (T--) {
ac.clear();
cin >> n;
rep_up0(i, n) {
scanf("%s", str);
ac.Insert(str);
}
scanf("%s", s);
ac.getFail();
ans = 0;
ac.find(s);
cout << ans << endl;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: