POJ 1625 Censored!

来源:互联网 发布:大数据时代的来临图画 编辑:程序博客网 时间:2024/04/30 20:57

AC自动机 + DP + 大数。网上说矩阵过不去,写了一发样例都没调出来直接放弃了。由于习惯性的把数组开大了,爆了两次,然后直接A了。注意大数为0的输出

#include<cstdio>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;#define N 2005#define INF 1000000009typedef long long LL;int n;int letter[300];struct Trie {    Trie *fail;    Trie *son[300];    int kind, isword;}s[N];Trie *que[N];int ptr;int id(unsigned char x){    return letter[x];}Trie *NewNode(){    Trie *p = &s[ptr];    for(int i = 0; i < n; i++)p->son[i] = NULL;    p->fail = NULL;    p->isword = 0;    p->kind = ptr++;    return p;}void Insert(unsigned char *c, Trie *root){    Trie *tmp = root;    for(int i = 0; c[i]; i++){        if(tmp->son[id(c[i])] == NULL) tmp->son[id(c[i])] = NewNode();        tmp = tmp->son[id(c[i])];    }    tmp->isword = 1;}void Build_fail(Trie *root){    Trie *tmp;    int head = 0, tail = 0;    que[tail++] = root;    root->fail = NULL;    while(head < tail){        tmp = que[head++];        for(int i = 0; i < n; i++){            if(tmp->son[i]){                if(tmp == root)tmp->son[i]->fail = root;                else {                    Trie *p = tmp->fail;                    while(p){                        if(p->son[i]){                            tmp->son[i]->fail = p->son[i];                            break;                        }                        p = p->fail;                    }                    if(p == NULL)tmp->son[i]->fail = root;                }                if(tmp->son[i]->fail->isword)tmp->son[i]->isword = 1;                que[tail++] = tmp->son[i];            }            else if(tmp == root)tmp->son[i] = root;            else tmp->son[i] = tmp->fail->son[i];        }    }}#define length 100class Bignum{    char s[length * 2];public :    Bignum(int x = 0){        memset(s, 0, sizeof(s));        s[0] = x;    }    void setnum(int x){        for(int i = 0; x; i++){            s[i] = x % 10;            x /= 10;        }    }    Bignum operator+(Bignum x){        Bignum ans;        for(int i = 0; i < length; i++){            ans.s[i] += s[i] + x.s[i];            ans.s[i + 1] += ans.s[i] / 10;            ans.s[i] %= 10;        }        return ans;    }    void print(){        int i = length;        while(s[i] == 0 && i >= 0)i--;        if(i == -1)printf("0");        while(i >= 0)printf("%d", s[i--]);        printf("\n");    }}dp[55][105];void solve(int tot){    dp[0][0].setnum(1);    Bignum zero;    for(int i = 1; i <= tot; i++){        for(int j = 0; j < ptr; j++){            Trie *tmp = &s[j];            if(tmp->isword)continue;            for(int k = 0; k < n; k++){                if(tmp->son[k]->isword)continue;                dp[i][tmp->son[k]->kind] = dp[i][tmp->son[k]->kind] + dp[i - 1][j];            }        }    }    Bignum ans;    for(int i = 0; i < ptr; i++){        ans = ans + dp[tot][i];    }    ans.print();}int main(){    int m, p;    while(scanf("%d%d%d", &n, &m, &p) != EOF){        ptr = 0;        Trie *root = NewNode();        unsigned char str[20];        unsigned char ms[55];        scanf("%s", ms);        memset(letter, 0, sizeof(letter));        for(int i = 0; ms[i]; i++)            letter[ms[i]] = i;        for(int i = 0; i < p; i++){            scanf("%s", str);            Insert(str, root);        }        Build_fail(root);        solve(m);    }    return 0;}


0 0
原创粉丝点击