[kuangbin带你飞]专题17:D

来源:互联网 发布:java 运行时获取注解 编辑:程序博客网 时间:2024/05/21 13:50

原题

AC自动机模版 + base64的解码

wa1 : 同个匹配串内多次出现的病毒只记录一次。
wa2 : 范围为256的部分特殊字符char的强制类型转换有问题(不确定)
解决:得到ascll码的int数组, 把int型数组作为匹配串直接去匹配

#include<iostream>#include<stack>#include<queue>#include<string>#include<cstring>#include<cstdio>#include<vector>using namespace std;const int MAXN = 50010;int map(char c) {    if(c >= 'A' && c <= 'Z') return c - 'A';    else if(c >= 'a' && c <= 'z') return  c - 'a' + 26;    else if(c >= '0' && c <= '9') return c - '0' + 52;    else if(c == '+') return 62;    else return 63;}int ascll[MAXN];int change(string s) {    //init    queue<int> q;       memset(ascll, 0, sizeof(ascll));    int l = (int)s.length();    for(int i = 0; i < l && s[i] != '='; i++) {        int temp = map(s[i]);        for(int i = 5; i >= 0; i--) q.push(temp>>i & 1);    }    int k = 0;    while(q.size() >= 8) {//8个一取,小于8时即代表剩下的都是添加的0        for(int i = 7; i >= 0; i--) {            if(q.front()) ascll[k] += 1<<i;            q.pop();        }        k++;    }    ascll[k] = -1;    return k;}int node[MAXN][256], fail[MAXN], End[MAXN];int root, L;bool vis[MAXN];int newnode() {    for(int i = 0; i < 256; i++) node[L][i] = -1;    fail[L] = -1;    End[L] = 0;    L++;    return L-1;}void init() {    L = 0;    root = newnode();}void insert(int l) {    int now = root;    for(int i = 0; i < l; i++) {        int id = ascll[i];        if(node[now][id] == -1) node[now][id] = newnode();        now = node[now][id];    }    End[now]++;}void setfail() {    queue<int> q;    q.push(root);    while(!q.empty()) {        int now = q.front(); q.pop();        for(int i = 0 ; i < 256; i++) if(node[now][i] != -1) {            int pre = fail[now];            while(pre != -1 && node[pre][i] == -1) pre = fail[pre];            fail[node[now][i]] = pre  == -1 ? root : node[pre][i];            q.push(node[now][i]);        }    }}int query(int l) {    int now = root;    int cnt = 0;    for(int i = 0; i < l; i++) {        int id = ascll[i];        while(now != -1 && node[now][id] == -1) now = fail[now];        now = now == -1 ? root : node[now][id];        for(int p = now; p != -1; p = fail[p]) if(End[p] && !vis[p]) {            cnt += End[p];            vis[p] = true;        }    }    return cnt;}int main() {    freopen("a.in", "r", stdin);    ios::sync_with_stdio(false);    int n;    string s;    while(cin >> n) {        init();        for(int i = 1; i <= n; i++) {            cin >> s; insert(change(s));        }        setfail();        cin >> n;        while(n--) {            memset(vis, false, sizeof(vis));            cin >> s; cout << query(change(s)) << endl;        }        cout << endl;    }    return 0;}
原创粉丝点击