poj 1625 Censored!

来源:互联网 发布:淘宝被投诉盗图扣分 编辑:程序博客网 时间:2024/04/30 16:03

题目链接:http://poj.org/problem?id=1625

题目大意:求不包含禁止串的长度为m的字符串个数。

题目思路:ac自动机,不过要用高精度,需要注意的是字符串有空格,而且要用无符号字符型,以前写的高精度用的是字符串模拟,这次见网上都用整型,且每一个整型数存多位十进制,而且效率很高,就果断学习了。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define Max 110#define mod 1000000000int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int q[11*11],cnt,n;unsigned char str[60];int mp[300];struct node{    int cnt,fail;    int next[50];    void init()    {        cnt=fail=0;        memset(next,0,sizeof(next));    }}tri[11*11];struct bignum{    int d[11];}c;bignum dp[55][110],ans;void add(bignum &a,bignum &b){    int i;    memset(c.d,0,sizeof(c.d));    int len=max(a.d[0],b.d[0]);    for(i=1;i<=len;i++)    {        if(i<=a.d[0])            c.d[i]+=a.d[i];        if(i<=b.d[0])            c.d[i]+=b.d[i];        c.d[i+1]+=c.d[i]/mod;        c.d[i]%=mod;        a.d[i]=c.d[i];    }    a.d[0]=len;    if(c.d[len+1])    {        a.d[len+1]=c.d[len+1];        a.d[0]=len+1;    }}void output(bignum ans){    int i,j;    printf("%d",ans.d[ans.d[0]]);    for(i=ans.d[0]-1;i>=1;i--)    {        printf("%09d",ans.d[i]);    }    puts("");}void insert(unsigned char *s){    int i,x,p;    p=0;    for(i=0;s[i];i++)    {        x=mp[s[i]];        if(!tri[p].next[x])        {            tri[++cnt].init();            tri[p].next[x]=cnt;        }        p=tri[p].next[x];    }    tri[p].cnt++;}void bfs(){    int i,p=0,suf,head=0,tail=0;    for(i=0;i<n;i++)    {        if(tri[0].next[i])        {            q[tail++]=tri[0].next[i];            tri[q[tail-1]].fail=0;        }    }    while(head<tail)    {        p=q[head++];suf=tri[p].fail;        tri[p].cnt+=tri[suf].cnt;        for(i=0;i<n;i++)        {            if(tri[p].next[i])            {                q[tail++]=tri[p].next[i];                tri[q[tail-1]].fail=tri[suf].next[i];            }            else                tri[p].next[i]=tri[suf].next[i];        }    }}void solve(int m){    int i,j,k;    for(i=0;i<=m;i++)        for(j=0;j<=cnt;j++)            dp[i][j].d[0]=0;    dp[0][0].d[0]=1;dp[0][0].d[1]=1;    for(i=0;i<m;i++)    {        for(j=0;j<=cnt;j++)        {            if(tri[j].cnt)                continue;            for(k=0;k<n;k++)            {                int tmp=tri[j].next[k];                if(!tri[tmp].cnt)                    add(dp[i+1][tmp],dp[i][j]);            }        }    }    ans.d[0]=1;ans.d[1]=0;    for(i=0;i<=cnt;i++)    {        if(!tri[i].cnt)            add(ans,dp[m][i]);    }}int main(){    int m,p,i,j;    while(scanf("%d%d%d",&n,&m,&p)!=EOF)    {        getchar();        cnt=0;tri[0].init();        for(i=0;(str[i]=getchar())!='\n';i++)            mp[str[i]]=i;        str[i]=0;        while(p--)        {            for(i=0;(str[i]=getchar())!='\n';i++);            str[i]=0;            insert(str);        }        bfs();        solve(m);        output(ans);    }}


 

 

原创粉丝点击