POJ1625 Censored!(AC自动机+DP)

题目问长度m不包含一些不文明单词的字符串有多少个。

依然是水水的AC自动机+DP。。做完后发现居然和POJ2778是一道题,回过头来看都水水的。。。

  • dp[i][j]表示长度i(在自动机转移i步)且后缀状态为自动机第j个结点的合法字符串数
  • dp[0][0]=1
  • 转移转移。。。

注意要用高精度,因为答案最多5050

还有就是要用unsigned char,题目的输入居然有拓展的ASCII码,编码128-255。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 int tn,ch[555][256],fail[555],flag[555];
 7 void insert(unsigned char *s){
 8     int x=0;
 9     for(int i=0; s[i]; ++i){
10         int y=s[i];
11         if(ch[x][y]==0) ch[x][y]=++tn;
12         x=ch[x][y];
13     }
14     flag[x]=1;
15 }
16 void init(){
17     memset(fail,0,sizeof(fail));
18     queue<int> que;
19     for(int i=0; i<256; ++i){
20         if(ch[0][i]) que.push(ch[0][i]);
21     }
22     while(!que.empty()){
23         int x=que.front(); que.pop();
24         for(int i=0; i<256; ++i){
25             if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i],flag[ch[x][i]]|=flag[ch[fail[x]][i]];
26             else ch[x][i]=ch[fail[x]][i];
27         }
28     }
29 }
30 #define ULL unsigned long long
31 #define M 1000000000000000000L
32 struct BigInt{
33     ULL bit[5];
34     BigInt(int a=0){
35         bit[0]=bit[1]=bit[2]=bit[3]=0;
36         bit[4]=a;
37     }
38 };
39 BigInt operator+(const BigInt &b1,const BigInt &b2){
40     BigInt b;
41     ULL carry=0;
42     for(int i=4; i>=0; --i){
43         ULL tmp=b1.bit[i]+b2.bit[i]+carry;
44         b.bit[i]=tmp%M;
45         carry=tmp/M;
46     }
47     return b;
48 };
49 void output(const BigInt &b){
50     int i=0;
51     while(i<5 && b.bit[i]==0) ++i;
52     if(i==5){
53         puts("0");
54         return;
55     }
56     printf("%llu",b.bit[i]);
57     for(int j=i+1; j<5; ++j){
58         printf("%018llu",b.bit[j]);
59     }
60     putchar('\n');
61 }
62 int main(){
63     BigInt one(1);
64     unsigned char str[55];
65     int n,m,p;
66     while(~scanf("%d%d%d",&n,&m,&p)){
67         scanf("%s",str);
68         bool vis[256]={0};
69         for(int i=0; str[i]; ++i) vis[str[i]]=1;
70         tn=0;
71         memset(ch,0,sizeof(ch));
72         memset(flag,0,sizeof(flag));
73         for(int i=0; i<p; ++i){
74             scanf("%s",str);
75             insert(str);
76         }
77         init();
78         BigInt **d=new BigInt*[m+1];
79         for(int i=0; i<=m; ++i) d[i]=new BigInt[tn+1];
80         d[0][0]=one;
81         for(int i=0; i<m; ++i){
82             for(int j=0; j<=tn; ++j){
83                 if(flag[j]) continue;
84                 for(int k=33; k<256; ++k){
85                     if(!vis[k] || flag[ch[j][k]]) continue;
86                     d[i+1][ch[j][k]]=d[i+1][ch[j][k]]+d[i][j];
87                 }
88             }
89         }
90         BigInt res=0;
91         for(int i=0; i<=tn; ++i) res=res+d[m][i];
92         output(res);
93         for(int i=0; i<=m; ++i) delete[] d[i];
94         delete[] d;
95     }
96     return 0;
97 }

 

posted @ 2016-01-31 21:19  WABoss  阅读(317)  评论(0编辑  收藏  举报