zoukankan      html  css  js  c++  java
  • [POJ2243]考研路茫茫——单词情结

      又是AC自动机上用矩乘优化DP= =

      其实和上一题基本一样。。。补集转化思想。。

      只是要多弄一个小矩阵求(26^1+26^2+....+26^L),并且也要求f的总和(因为是长度<=L)

      直接调上一题的伪板子了= =

      喜闻乐见CE了好几发。。。就因为iostream里有next这个名字的函数>_<(那我上一题怎么没CE啊摔

      1 #include<cstdio>
      2 #include<cstring>
      3 #define ll long long
      4 #define ull unsigned long long
      5 using namespace std;
      6 int dl[33],fail[33],num[33];
      7 int ch[33][26],tot,next[33][26];
      8 ull mp[36][36];
      9 ull c[36][36],tmp[36][36],ans;
     10 int i,j,k,n,m,l,r,cnt;
     11 bool gg[103];
     12 char s[23];
     13 
     14 ll tm[103],t[103];
     15 
     16 inline void trie(int n){
     17     int i,p=0;
     18     for(i=0;i<n;i++){
     19         s[i]-='a';
     20         if(!ch[p][s[i]])ch[p][s[i]]=++tot,p=tot;
     21         else p=ch[p][s[i]];
     22     }
     23     gg[p]=1;//printf("gg:  %d
    ",p);
     24 }
     25 inline void getfail(){
     26     int l=0,r=1,i,j,now,p;dl[1]=0;
     27     while(l<r){
     28         now=dl[++l];//printf("   %d  fail:%d    gg:%d
    ",now,fail[now],gg[now]);
     29         for(i=0;i<26;i++)if(ch[now][i]){
     30             j=ch[now][i];//printf("  %d-->%d
    ",now,j);
     31             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
     32             if(!now)fail[j]=0;else fail[j]=ch[p][i];
     33             dl[++r]=j;gg[j]|=gg[fail[j]];
     34         }
     35     }
     36 }
     37 inline void getnext(){
     38     l=0,r=1;int i,now,p;dl[1]=0;
     39     while(l<r){
     40         now=dl[++l];//printf("    %d
    ",now);
     41         for(i=0;i<26;i++){
     42             if(ch[now][i]){
     43                 if(gg[ch[now][i]])next[now][i]=-1;
     44                 else next[now][i]=ch[now][i],dl[++r]=ch[now][i];
     45             }
     46             else{
     47                 for(p=fail[now];p&&!ch[p][i];p=fail[p]);
     48                 next[now][i]=gg[ch[p][i]]?-1:ch[p][i];
     49             }
     50 //            printf("%d %d  next:%d
    ",now,i,next[now][i]);
     51         }
     52     }
     53 }
     54 inline void upd(){
     55     cnt=0;int i,j;
     56     for(i=1;i<=r;i++)
     57         num[dl[i]]=++cnt;
     58     for(i=1;i<=r;i++){
     59         j=dl[i];
     60         for(k=0;k<26;k++)if(next[j][k]!=-1)
     61             mp[num[next[j][k]]][num[j]]++;
     62     }
     63     
     64 //    for(i=1;i<=r;puts(""),i++)
     65 //        for(j=1;j<=r;j++)printf("   %lld",mp[i][j]);
     66 }
     67 
     68 
     69 inline void multoc(){
     70     register int i,j,k;
     71     for(i=1;i<=cnt;i++)
     72     for(j=1;j<=cnt;j++)
     73         for(tmp[i][j]=0,k=1;k<=cnt;k++)tmp[i][j]+=mp[i][k]*c[k][j];
     74     for(i=1;i<=cnt;i++)memcpy(c[i],tmp[i],(cnt+1)<<3);
     75 }
     76 inline void multomp(){
     77     register int i,j,k;
     78     for(i=1;i<=cnt;i++)
     79     for(j=1;j<=cnt;j++)
     80         for(tmp[i][j]=0,k=1;k<=cnt;k++)tmp[i][j]+=mp[i][k]*mp[k][j];
     81     for(i=1;i<=cnt;i++)memcpy(mp[i],tmp[i],(cnt+1)<<3);
     82 }
     83 
     84 int main(){
     85     while(scanf("%d%d",&n,&m)!=EOF){
     86         for(i=1;i<=n;i++)scanf("%s",s),trie(strlen(s));
     87         getfail(),getnext(),upd();
     88         cnt++;
     89         for(i=1;i<=cnt;i++)mp[cnt][i]=1;
     90         cnt++,mp[cnt][cnt]=26,cnt++,mp[cnt][cnt-1]=mp[cnt][cnt]=1;
     91         
     92     //    for(i=1;i<=cnt;puts(""),i++)for(j=1;j<=cnt;j++)printf("  %llu",mp[i][j]);
     93         
     94         for(i=1;i<=cnt;i++)c[i][i]=1;
     95         
     96 /*        tm[1]=1;
     97         for(i=1;i<=m;i++){
     98             for(j=1;j<=cnt;j++)
     99                 for(k=1,t[j]=0;k<=cnt;k++)t[j]=(t[j]+mp[j][k]*tm[k])%modd;
    100             memcpy(tm,t,sizeof(t));
    101         }*/
    102         
    103         while(m){
    104             if(m&1)
    105                 multoc();
    106             m>>=1;if(m)multomp();
    107 //        for(i=1;i<=cnt;puts(""),i++)for(j=1;j<=cnt;j++)printf("  %llu",c[i][j]);
    108         }
    109         
    110 //        for(i=1;i<=cnt;puts(""),i++)for(j=1;j<=cnt;j++)printf("  %llu",c[i][j]);
    111         //for(i=1,ans=0;i<=cnt;i++)ans=(ans+c[i][1])%modd;
    112         ull ans=c[cnt][cnt-1]*26;
    113         for(i=1;i<=cnt-2;i++)ans-=c[i][1];
    114         printf("%I64u
    ",ans+1);
    115         
    116         memset(mp,0,sizeof(mp)),memset(c,0,sizeof(c)),
    117         memset(ch,0,(tot+1)*4*26),memset(next,0,(tot+1)*4*26),memset(fail,0,(tot+1)<<2),memset(gg,0,tot+1),tot=0;
    118     }
    119     //    for(i=1,ans=0;i<=cnt;i++)ans=(ans+tm[i])%modd;
    120     //    printf("%lld
    ",ans);
    121     return 0;
    122 }
    View Code
  • 相关阅读:
    [转]趣题:一个n位数平均有多少个单调区间?---- From Matrix67
    2015编程之美复赛
    Codeforces Round #304 (Div. 2)
    HDU 5226
    HDU 5225
    HDU 3666
    HDU 4598
    Codeforces Round #303 (Div. 2) E
    编程之美初赛第二场AB
    2015 编程之美初赛第一场 AC题
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5335028.html
Copyright © 2011-2022 走看看