zoukankan      html  css  js  c++  java
  • hdu 6086 Rikka with String(AC自动机+状压dp)

    题目链接:hdu 6086 Rikka with String

    题意:

    给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]s[|s|i+1] for all i[1,|s|] ,长度为2L,并且包含给出的n个串,问能有多少种这样的串。

    题解:

    建立两个AC自动机,一个用来放正串,一个用来放反串。

    由于题目有限制条件,所以前L长度的字符一确定,后L长度的字符就确定了。

    所以考虑dp[i][j][k][u],表示长度为i,第一个ac自动机走到了j这个节点,第二个ac自动机走到了k这个节点,当前包含子串的状态为u。

    第一维可以滚动数组。

    然后这样dp完后,只能找到包含的串要么在左边L里要么在右边L里,对于跨越分界线的串,还没有算进去。

    然后我们在将第L长度的dp状态进行暴力枚举,将j,k节点所代表的前缀拿来合并,进行对给出的串暴力匹配一下。

    然后就可以算到全部的情况了。

      1 #include<bits/stdc++.h>
      2 #define mst(a,b) memset(a,b,sizeof(a))
      3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
      4 using namespace std;
      5 
      6 const int AC_N=200+7,tyn=2;
      7 int t,n,L,P=998244353;
      8 char s[8][30],pre[200][30],suf[200][30];
      9 int dp[2][130][130][1<<6];
     10 
     11 inline void up(int &a,int b){a=(a+b)%P;}
     12 
     13 struct AC_automation{
     14     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
     15     inline int getid(char x){return x-'0';}
     16     void nw(){cnt[++tot]=0,fail[tot]=0;mst(tr[tot],0);}
     17     void init(){tot=-1,fail[0]=-1,nw();}
     18     void insert(char *s,int idx,char p[][30],int x=0){
     19         for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++)
     20             if(!tr[x][w=getid(s[i])])
     21             {
     22                 nw(),tr[x][w]=tot;
     23                 strcpy(p[tot],p[x]);
     24                 int Len=strlen(p[x]);
     25                 p[tot][Len]=w+'0';
     26                 p[tot][Len+1]=0;
     27             }
     28         cnt[x]=1<<(idx-1);
     29     }
     30     void build(int head=1,int tail=0){
     31         for(int i=0;i<tyn;i++)if(tr[0][i])Q[++tail]=tr[0][i];
     32         while(head<=tail)for(int x=Q[head++],i=0;i<tyn;i++)
     33             if(tr[x][i])
     34             {
     35                 fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
     36                 cnt[tr[x][i]]|=cnt[tr[fail[x]][i]];
     37             }
     38             else tr[x][i]=tr[fail[x]][i];
     39     }
     40 }A,B;
     41 
     42 void solve()
     43 {
     44     int now=0;
     45     mst(dp[now],0),dp[now][0][0][0]=1;
     46     int U=(1<<n)-1;
     47     F(i,1,L)
     48     {
     49         now^=1,mst(dp[now],0);
     50         F(j,0,A.tot)F(k,0,B.tot)F(u,0,U)
     51         if(dp[now^1][j][k][u])
     52         {
     53             int nx=A.tr[j][0],nx2=B.tr[k][1];
     54             up(dp[now][nx][nx2][u|A.cnt[nx]|B.cnt[nx2]],dp[now^1][j][k][u]);
     55             nx=A.tr[j][1],nx2=B.tr[k][0];
     56             up(dp[now][nx][nx2][u|A.cnt[nx]|B.cnt[nx2]],dp[now^1][j][k][u]);
     57         }
     58     }
     59     char tmp[300],tp[40];
     60     F(i,1,A.tot)F(j,1,B.tot)F(u,0,U-1)
     61         if(dp[now][i][j][u])
     62         {
     63             strcpy(tmp,pre[i]);
     64             strcpy(tp,suf[j]);
     65             reverse(tp,tp+strlen(tp));
     66             strcat(tmp,tp);
     67             int ttp=0;
     68             F(ii,1,n)
     69             {
     70                 if(strstr(tmp,s[ii])!=0)
     71                     ttp|=(1<<(ii-1));
     72             }
     73             if((u|ttp)==U)
     74                 up(dp[now][i][j][U],dp[now][i][j][u]);
     75         }
     76     int ans=0;
     77     F(i,0,A.tot)F(j,0,B.tot)if(dp[now][i][j][U])
     78         up(ans,dp[now][i][j][U]);
     79     printf("%d
    ",ans);
     80 }
     81 
     82 int main()
     83 {
     84     scanf("%d",&t);
     85     while(t--)
     86     {
     87         A.init(),B.init();
     88         scanf("%d%d",&n,&L);
     89         F(i,1,n)
     90         {
     91             scanf("%s",s[i]);
     92             A.insert(s[i],i,pre);
     93             char tmp[30];
     94             strcpy(tmp,s[i]);
     95             reverse(tmp,tmp+strlen(tmp));
     96             B.insert(tmp,i,suf);
     97         }
     98         A.build(),B.build();
     99         solve();
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    IO模型
    Java NIO概述
    消息系统避免分布式事务
    JVM调优总结
    设计模式的六大原则
    Java 内存区域与内存溢出
    windows go安装
    ZooKeeper原理及使用
    再谈HashMap
    Html5 播放实时音频流
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7325505.html
Copyright © 2011-2022 走看看