题目链接

Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has n 01 strings si, and he wants to know the number of 01 antisymmetric strings of length 2L which contain all given strings si as continuous substrings.

A 01 string s is antisymmetric if and only if s[i]≠s[|s|−i+1] for all i∈[1,|s|].

It is too difficult for Rikka. Can you help her?

In the second sample, the strings which satisfy all the restrictions are 000111,001011,011001,100110.

Input
The first line contains a number t(1≤t≤5), the number of the testcases.

For each testcase, the first line contains two numbers n,L(1≤n≤6,1≤L≤100).

Then n lines follow, each line contains a 01 string si(1≤|si|≤20).

Output
For each testcase, print a single line with a single number -- the answer modulo 998244353.
Sample Input
2
2 2
011
001
2 3
011
001

Sample Output
1
4
题意:反对称:对于一个长为2*N的串s[0~2*N-1],s[i]^s[2*N-1-i]=1 。现在有n个01串,求有多少个长为2*L的并且包含这n个串的 反对称01串?
思路:对于一个串包含在2*L的01串中,那么这个串要么在2*L的前半部分,要么后半部分,或者跨越中间,如果在后半部分,则需要找到其在前半部分的反对称01串,对于跨越中间的01串,则需要找到其在前面部分的串,例如:0 | 11,以竖线作为串中间,那么如果前面部分如果以00结束,那么一定含有 011这个串。把每个串的所有形式放入AC自动机对应的tire树中,然后状压递推。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
const int mod=998244353;
const int N=2005;
struct Node{int id;Node *fail;Node *son[2];int tag1,tag2;
}node[N];
queue<Node *>q;
int tot;
int dp[2][2005][64];void insert1(string s,int id)
{int len=s.length();Node *now=&node[0];for(int i=0;i<len;i++){int x=s[i]-'0';if(now->son[x]==NULL) now->son[x]=&node[tot++];now=now->son[x];}now->tag1|=(1<<id);
}
void insert2(string s,int id)
{int len=s.length();Node *now=&node[0];for(int i=0;i<len;i++){int x=s[i]-'0';if(now->son[x]==NULL) now->son[x]=&node[tot++];now=now->son[x];}now->tag2|=(1<<id);
}
void init()
{for(int i=0;i<N;i++){node[i].id=i;node[i].fail=NULL;node[i].son[0]=node[i].son[1]=NULL;node[i].tag1=node[i].tag2=0;}
}
void setFail()
{Node* root=&node[0];q.push(root);while(!q.empty()){Node* now=q.front(); q.pop();for(int i=0;i<2;i++){if(now->son[i]){Node* p=now->fail;while(p && (!(p->son[i]))) p=p->fail;now->son[i]->fail=(p)?(p->son[i]):(root);now->son[i]->tag1|=now->son[i]->fail->tag1;now->son[i]->tag2|=now->son[i]->fail->tag2;q.push(now->son[i]);}else now->son[i]=(now!=root)?now->fail->son[i]:(root);}}
}
void print()
{Node* now=&node[0];queue<Node*>qq;qq.push(now);while(!qq.empty()){now=qq.front(); qq.pop();cout<<"Y:"<<now->id<<" ";for(int i=0;i<2;i++){if(now->son[i]) qq.push(now->son[i]),cout<<now->son[i]->id<<" ";else cout<<"NULL"<<" ";}cout<<endl;}
}
int main()
{///cout << "Hello world!" << endl;
    int t; cin>>t;while(t--){init();tot=1;int n,L; scanf("%d%d",&n,&L);for(int i=0;i<n;i++){string s; cin>>s;insert1(s,i);string t=s;reverse(t.begin(),t.end());int len=s.length();for(int j=0;j<len;j++)t[j]=(char)((t[j]-'0')^1+'0');insert1(t,i);int mnLen=min(len,L);for(int j=0;j<mnLen;j++){int f=1;for(int l=j,r=j+1; l>=0&&r<len; l--,r++){if((s[l]^s[r])==0) { f=0; break; }}if(!f) continue;t=s.substr(0,j+1);for(int k=2*j+2;k<len;k++){t=(char)((s[k]-'0')^1+'0')+t;}insert2(t,i);}}///print();
       setFail();memset(dp,0,sizeof(dp));dp[0][0][0]=1;int cn=0,stu=(1<<n);for(int i=0;i<L;i++){int c=cn^1;memset(dp[c],0,sizeof(dp[c]));for(int j=0;j<tot;j++){for(int s=0;s<stu;s++){if(!dp[cn][j][s]) continue;if(i<L-1)for(int k=0;k<2;k++){int x=node[j].son[k]->id;int tag=node[x].tag1;dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;}elsefor(int k=0;k<2;k++){int x=node[j].son[k]->id;int tag=node[x].tag1|node[x].tag2;dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;}}}cn=c;}int ans=0;for(int i=0;i<tot;i++){ans=(ans+dp[cn][i][stu-1])%mod;}printf("%d\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/chen9510/p/7406636.html

hdu 6086 -- Rikka with String(AC自动机 + 状压DP)相关推荐

  1. 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|] ,长度 ...

  2. HDU - 3341 Lost's revenge(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 n 个模式串,最后给出一个匹配串,问如何重新排列匹配串,可以使得匹配串尽可能多的匹配模式串 题目分析:因为是模式串和匹配串的匹配,所以考虑AC自动机,因为数据范围比 ...

  3. HDU - 2825 Wireless Password(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 m 个匹配串,问长度为 n 的字符串中,至少包含 k 个匹配串(可重叠)的字符串有多少个 题目分析:考虑到n,m,k都特别小,所以可以先用AC自动机将状态关系转移出 ...

  4. HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)

    题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...

  5. HDU - 2825 Wireless Password (AC自动机 + 状压dp)

    题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...

  6. 【hdu2825】ac自动机 + 状压dp

    传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...

  7. AC自动机+状压dp hdu2825 Wireless Password

    传送门:点击打开链接 题意:有个密码长度为n,现在有m个魔力单词,要求密码中魔力单词的种类数>=k,问这种密码的种类数. 思路:和之前一样,我们会想到AC自动机去压缩状态,把状态给简化.然后我们 ...

  8. P4045-[JSOI2009]密码【AC自动机,状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4045 题目大意 给nnn个字符串,求有多少个长度为lll的字符串包含所有给出的字符串 解题思路 因为nnn很小, ...

  9. *【HDU - 4272 】LianLianKan (dfs 或 状压dp,贪心不行)

    题干: I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new ...

最新文章

  1. 实践 Neutron 前的两个准备工作 - 每天5分钟玩转 OpenStack(78)
  2. centos 重启网卡_CentOS7网络配置和修改网卡名称及常用服务管理命令
  3. web3@0.20.1 在依据abi创建智能合约的时候报错 TypeError: web3.eth.contract is not a function
  4. hibernate 程序运行时的错误,及解决办法(不定期更新)
  5. failed to open log file_C++中glog源码剖析以及如何设计一个高效 log模块
  6. charles工具页面介绍
  7. columns列:Rows 工作表上所有的行
  8. 6.Java反射到底慢在哪
  9. 线性表的总结:顺序存储线性表的初始化,创建,插入,删除,清空,销毁等操作...
  10. Hyperledger Fabric 节点类型Commiter、Endorser、Leader、Anchor
  11. java8计算两个日期之间的天数
  12. 免费直播|1小时详解区块链技术
  13. 电子器件系列二十一:混频器
  14. Windows cmd常用命令
  15. html5 地铁 代码,基于HTML5WebGL的地铁管理系统
  16. 网络编辑必知常识:什么是PV、UV和PR值
  17. ONEDNS配置1:centos7DNS服务器forwarder配置
  18. 每个c语言程序文件的编译错误被分为什么,已打印中央电大C语言考试题库(c语言小题+编程)...
  19. 硬件在环系统环境架构
  20. 经济学方面的电子书挺多

热门文章

  1. 【POJ - 3320 】Jessica's Reading Problem (尺取,哈希)
  2. 动手学无人驾驶(4):基于激光雷达点云数据3D目标检测
  3. 11.Pipelines
  4. java web svn_如何搭建svnadmin,一个简单的svnWEB页面
  5. 判断集合相等_数学启蒙的每个关键阶段之集合分类
  6. Callable创建多线程
  7. char qt 转unicode_Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题...
  8. Jquery 全选,反选
  9. 学习笔记1-Linux1
  10. 求1~n这n个整数十进制表示中1出现的次数