zoukankan      html  css  js  c++  java
  • bzoj 1030

    单词建出AC自动机,然后在自动机上做DP

    d[i][j]表示第i个字符匹配到节点j上的方案数

    直接算有点麻烦,统计不满足的方案数就好了

     1 #include<bits/stdc++.h>
     2 #define inc(i,l,r) for(int i=l;i<=r;i++)
     3 #define dec(i,l,r) for(int i=l;i>=r;i--)
     4 #define link(x) for(edge *j=h[x];j;j=j->next)
     5 #define mem(a) memset(a,0,sizeof(a))
     6 #define inf 10007
     7 #define ll long long
     8 #define succ(x) (1<<x)
     9 #define lowbit(x) (x&(-x))
    10 #define ida(x) (x-'A')
    11 #define NM 100+5
    12 using namespace std;
    13 int read(){
    14     int x=0,f=1;char ch=getchar();
    15     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    16     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    17     return x*f;
    18 }
    19 const int cnt=25;
    20 struct node{
    21     node *c[cnt+1],*f;
    22     bool s;
    23     int id;
    24 }N[100*NM],*o=N,*root;
    25 node* newnode(){
    26     o->id=o-N;o->f=root;o->s=0;return o++;
    27 }
    28 char st[NM];
    29 int n,m,d[100*NM],f[100*NM],ans;
    30 void ins(){
    31     node *r=root;
    32     scanf("%s",st);int len=strlen(st)-1;
    33     inc(i,0,len){
    34         if(!r->c[ida(st[i])])r->c[ida(st[i])]=newnode();
    35         r=r->c[ida(st[i])];
    36     }
    37     r->s=true;
    38 }
    39 void bfs(){
    40     queue<node*>q;
    41     inc(i,0,cnt)if(root->c[i])q.push(root->c[i]);
    42     while(!q.empty()){
    43         node *t=q.front();q.pop();
    44         inc(i,0,cnt)if(t->c[i]){
    45             node *r=t->f;
    46             while(r!=root&&!r->c[i])r=r->f;
    47             t->c[i]->f=r->c[i]?r->c[i]:root;
    48             if(t->c[i]->f->s)t->c[i]->s=true;
    49             q.push(t->c[i]);
    50         }
    51     }
    52 }
    53 void dp(node *r){
    54     if(r->s)return;
    55     inc(i,0,cnt)if(r->c[i]){
    56         (d[r->c[i]->id]+=f[r->id])%=inf;
    57         dp(r->c[i]);
    58     }else{
    59         node *t=r->f;
    60         while(t!=root&&!t->c[i])t=t->f;
    61         if(t->c[i])(d[t->c[i]->id]+=f[r->id])%=inf;else (d[0]+=f[r->id])%=inf;
    62     }
    63 }
    64 void dfs(node *r){
    65     if(r->s)return;
    66     inc(i,0,cnt)if(r->c[i])dfs(r->c[i]);
    67     (ans+=inf-f[r->id])%=inf;
    68 }
    69 int main(){
    70 //    freopen("data.in","r",stdin);
    71     root=newnode();root->f=root;
    72     n=read();m=read();
    73     inc(i,1,n)ins();
    74     bfs();ans=1;f[0]++;
    75     inc(i,1,m){
    76         (ans*=26)%=inf;
    77         dp(root);
    78         memcpy(f,d,sizeof(d));mem(d);
    79 //        inc(i,0,o-N)printf("%d ",f[i]);printf("
    ");
    80     }
    81     dfs(root);
    82     printf("%d
    ",ans);
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    NOI2015 品酒大会
    BJOI2017 喷式水战改
    代码注释
    mysql zip 安装 和 修改密码
    Jrebel 永久免费激活步骤
    layui 在springboot2.x 时,页面展示不了layui的问题
    最小生成树
    loj 10117 简单题(cqoi 2006)
    vijos 1512 SuperBrother打鼹鼠
    vijos 清点人数
  • 原文地址:https://www.cnblogs.com/onlyRP/p/5194126.html
Copyright © 2011-2022 走看看