zoukankan      html  css  js  c++  java
  • 【XSY2989】字符串

    题目来源:NOI2018模拟测试赛(二十六)

    题解:

    首先由于这是个01串,所以反对称串的意思就是这个字符串的后半部分是前半部分的反转且翻转结果;

    一个串出现有三种情况:在前半部分,在后半部分或穿过中间;

    对于前两种情况,由于n很小,可以直接在AC自动机跑状压DP,对于第三种情况特殊处理一下,就是对于所有子串的所有前缀,判断以这个前缀为结尾能否构造出这个串,有则累加答案就好了,具体见代码。

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 #define eps 1e-9
     9 #define mod 998244353
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double db;
    13 struct ac{
    14     int fa,fail,son[2],s,t;
    15 }t[200001];
    16 int n,m,nw,tmp,ans=0,len,cnt=0,num[2001],f[2][2001][64];
    17 char s[101];
    18 void ins(char *s,int len,int id){
    19     int nw=0;
    20     for(int i=1;i<=len;i++){
    21         if(!t[nw].son[s[i]-'0']){
    22             t[nw].son[s[i]-'0']=++cnt;
    23             num[cnt]=s[i]-'0';
    24             t[cnt].fa=nw;
    25         }
    26         nw=t[nw].son[s[i]-'0'];
    27     }
    28     t[nw].s|=(1<<id-1);
    29 }
    30 void AC(){
    31     queue<int>q;
    32     for(int i=0;i<=1;i++){
    33         if(t[0].son[i]){
    34             q.push(t[0].son[i]);
    35             t[t[0].son[i]].fail=0;
    36         }
    37     }
    38     while(!q.empty()){
    39         int u=q.front();
    40         q.pop();
    41         t[u].s|=t[t[u].fail].s;
    42         for(int i=0;i<=1;i++){
    43             if(t[u].son[i]){
    44                 t[t[u].son[i]].fail=t[t[u].fail].son[i];
    45                 q.push(t[u].son[i]);
    46             }else t[u].son[i]=t[t[u].fail].son[i];
    47         }
    48     }
    49 }
    50 int getfa(int u){
    51     int ret=0;
    52     for(int nw=u;nw;nw=t[nw].fa){
    53         u=t[u].son[num[nw]^1];
    54         ret|=t[u].s;
    55     }
    56     return ret;
    57 }
    58 int main(){
    59     scanf("%d%d",&n,&m);
    60     for(int i=1;i<=n;i++){
    61         scanf("%s",s+1);
    62         len=strlen(s+1);
    63         ins(s,len,i);
    64         reverse(s+1,s+len+1);
    65         for(int j=1;j<=len;j++){
    66             s[j]=((s[j]-'0')^1)+'0';
    67         }
    68         ins(s,len,i);
    69     }
    70     AC();
    71     f[0][0][0]=1;
    72     for(int tt=1;tt<=m;tt++){
    73         nw^=1;
    74         memset(f[nw],0,sizeof(f[nw]));
    75         for(int i=0;i<=cnt;i++){
    76             for(int j=0;j<(1<<n);j++){
    77                 for(int k=0;k<=1;k++){
    78                     f[nw][t[i].son[k]][j|t[t[i].son[k]].s]=(f[nw][t[i].son[k]][j|t[t[i].son[k]].s]+f[nw^1][i][j])%mod;
    79                 }
    80             }
    81         }
    82     }
    83     for(int i=0;i<=cnt;i++){
    84         tmp=getfa(i);
    85         for(int j=0;j<(1<<n);j++){
    86             if((tmp|j)==(1<<n)-1){
    87                 ans=(ans+f[nw][i][j])%mod;
    88             }
    89         }
    90     }
    91     printf("%d",ans);
    92     return 0;
    93 }
  • 相关阅读:
    uva 1510
    ADN中国团队參加微软的Kinect全国大赛获得三等奖
    在 window7 window8下公布webService注意问题
    html5调用手机摄像头,实现拍照上传功能
    4、深入理解Bean
    恶补jquery(四)jquery中事件--冒泡
    html5css3杂记
    Core Data 和 sqlite3的性能对比【图】3gs,iPhone4,4s,5的性能测试。
    boost 的函数式编程库 Phoenix入门学习
    information_schema模式表介绍 processlist
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/10062939.html
Copyright © 2011-2022 走看看