poj 2778 AC自动机DP

从AC了poj1625 censored!一题后,又解决了一道AC自动机DP题。

【题意】

同poj 1625

【题解】

poj 1625是dp,而这道题的DP通过矩阵实现。

【代码】

#include 
#include 
using namespace std;
const int maxn=100,base=100000,kind=4;

struct node
{
       int sum,id;
       node* ch[kind];
       node* fail;
}a[maxn];
int ans[maxn][maxn],f[maxn][maxn];
int tot=0,m,n;

node* getroot()
{
      tot++;
      int i;
      for (i=0;ich[k]==0)
            now->ch[k]=getnode();
         now=now->ch[k];
     }
     now->sum++;
}
 
queue q;
void build()
{
     int i,k;
     node* now,*ff;
     q.push(root);
     while (!q.empty())
     {
           now=q.front();
           q.pop();
           for (i=0;ich[i]!=0)
               {
                  q.push(now->ch[i]);
                  for (ff=now->fail;ff!=0;ff=ff->fail)
                      if (ff->ch[i]!=0)
                      {
                         now->ch[i]->fail=ff->ch[i];
                         if (ff->ch[i]->sum==1) now->ch[i]->sum=1;//很重要
                         break;
                      }
               }
     }
}

void init()
{
     cin >> m >> n;
     int i;
     char s[maxn];
     for (i=1;i<=m;i++)
     {
         cin >> s;
         ins(s);
     }
}

void get_matrix()
{
     node* now,*tmp;
     int i,j,ct;
     for (i=1;i<=tot;i++)
         for (j=0;jch[j]!=0)
             {
                ct=now->ch[j]->id;
                if (now->ch[j]->sum==0) f[ct][i]++;
             }
             else
             {
                 for (tmp=now->fail;tmp!=0;tmp=tmp->fail)
                     if (tmp->ch[j]!=0)
                        break;
                 if (tmp!=0) tmp=tmp->ch[j];
                 else tmp=root;
                 ct=tmp->id;
                 if (tmp->sum==0) f[ct][i]++;
             }
         }
}

void mul(int a[][maxn],int b[][maxn])
{
     int i,j,k;
     int c[maxn][maxn]={0};
     for (i=1;i<=tot;i++)
         for (j=1;j<=tot;j++)
             for (k=1;k<=tot;k++)
             {
                 long long tt=a[i][k];
                 tt=(tt*b[k][j])%base;
                 c[i][j]=(c[i][j]+int(tt))%base;
             }
     for (i=1;i<=tot;i++)
         for (j=1;j<=tot;j++)
             a[i][j]=c[i][j];
}

int cal()
{
     int i,sum;
     for (i=1;i<=tot;i++)
         ans[i][i]=1;
     while (n)
     {
           if (n&1)
              mul(ans,f);
           mul(f,f);
           n>>=1;
     }
     sum=0;
     for (i=1;i<=tot;i++)
         sum+=ans[i][1];
     return sum%base;
}

int main()
{
    freopen("pin.txt","r",stdin);
    freopen("pou.txt","w",stdout);
    init();
    build();
    get_matrix();
    cout << cal() << endl;
    return 0;
}


你可能感兴趣的:(acm_动态规划,acm_数据结构)