• bzoj1030 [JSOI2007]文本生成器


    题目链接

    AC自动机+DP

    有点像GT考试,hh[i][j]表示第i为匹配到自动机上j号结点的方案数

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<string>
     7 #include<cmath>
     8 #include<ctime>
     9 #include<queue>
    10 #include<stack>
    11 #include<map>
    12 #include<set>
    13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
    14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
    15 #define Clear(a,b) memset(a,b,sizeof(a))
    16 #define inout(x) printf("%d",(x))
    17 #define douin(x) scanf("%lf",&x)
    18 #define strin(x) scanf("%s",(x))
    19 #define LLin(x) scanf("%lld",&x)
    20 #define op operator
    21 #define CSC main
    22 typedef unsigned long long ULL;
    23 typedef const int cint;
    24 typedef long long LL;
    25 using namespace std;
    26 void inin(int &ret)
    27 {
    28     ret=0;int f=0;char ch=getchar();
    29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
    30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
    31     ret=f?-ret:ret;
    32 }
    33 int n,m,ch[6060][26],pre[6060],hh[111][6060],v[6060],ed=1,last[6060];
    34 char s[1010];
    35 void add(char *s,int x)
    36 {
    37     int temp=1,len=strlen(s);
    38     re(i,0,len-1)
    39     {
    40         int c=s[i]-'A';
    41         if(!ch[temp][c])ch[temp][c]=++ed;
    42         temp=ch[temp][c];
    43     }
    44     v[temp]=x;
    45 }
    46 void getfail()
    47 {
    48     queue<int>h;int k;
    49     h.push(1);
    50     while(!h.empty())
    51     {
    52         int x=h.front();h.pop();
    53         re(i,0,25)
    54         {
    55             if(!ch[x][i])continue;
    56             int vv=ch[x][i];
    57             h.push(vv);
    58             k=pre[x];
    59             while(!ch[k][i])k=pre[k];
    60             pre[vv]=ch[k][i];
    61             if(v[ch[k][i]])v[ch[x][i]]=v[ch[k][i]];
    62             last[vv]=v[pre[vv]]?pre[vv]:last[pre[vv]];
    63         }
    64     }
    65 }
    66 cint mod=10007;
    67 void dp(int x)
    68 {
    69     re(i,1,ed)
    70     {
    71         if(v[i]||!hh[x-1][i])continue;
    72         re(j,0,25)
    73         {
    74             int k=i;
    75             while(!ch[k][j])k=pre[k];
    76             (hh[x][ch[k][j]]+=hh[x-1][i])%=mod;
    77         }
    78     }
    79 }
    80 int main()
    81 {
    82     inin(n),inin(m);
    83     re(i,0,25)ch[0][i]=1;
    84     re(i,1,n)
    85     {
    86         strin(s);
    87         add(s,i);
    88     }
    89     getfail();
    90     hh[0][1]=1;
    91     re(i,1,m)dp(i);
    92     int ans1=0,ans2=1;
    93     re(i,1,m)ans2=ans2*26%mod;
    94     re(i,1,ed)if(!v[i])(ans1+=hh[m][i])%=mod;
    95     printf("%d",(ans2-ans1+mod)%mod);
    96      return 0;
    97 }
  • 相关阅读:
    Code review
    一点心得
    有关双向追踪性的一点感觉
    测试用例分析的一点心得
    js简单的抽屉菜单
    新的感受
    linux的VPS如何分区
    PHP中Unicode转码和解码的实现
    xampp安装及配置
    js Unicode编码转换
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5226296.html
Copyright © 2020-2023  润新知