Rikka with String

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
 
 
题解:
  要是能在比赛中A掉就爽了
  和题解做法一样
  

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 1e4+, M = 1e3+,inf = 2e9; const LL mod = 998244353LL; int dp[][][][],sum[][N];
int nex[][N][],cnt0,cnt1,head1,tail1,head0,tail0,q[][N],fail[][N]; void insert(char *s,int p) {
int now = ,len = strlen(s);
for(int i = ; i < len; ++i) {
int index = s[i] - '';
if(!nex[][now][index])
nex[][now][index] = ++cnt0;
sum[][nex[][now][index]] |= sum[][now];
now = nex[][now][index];
//cout<<now<<" "<<index<<endl;
}
sum[][now] |= (<<p); now = ;
for(int i = len-; i >= ; --i) {
int index = s[i] - '';
if(!nex[][now][index])
nex[][now][index] = ++cnt1;
sum[][nex[][now][index]] |= sum[][now];
now = nex[][now][index];
//cout<<now<<" "<<index<<endl;
}
sum[][now] |= (<<p);
} void build_fail() {
head0 = , tail0 = ;head1 = , tail1 = ;
for(int i = ; i < ; ++i)
nex[][][i] = ,nex[][][i] = ; fail[][] = ,fail[][] = ;
q[][tail0++] = ;q[][tail1++] = ;
while(head0 != tail0) {
int now = q[][head0++];
sum[][now] |= sum[][fail[][now]];
for(int i = ; i < ; ++i) {
int p = fail[][now];
if(!nex[][now][i]) {
nex[][now][i] = nex[][p][i];continue;
}
fail[][nex[][now][i]] = nex[][p][i];
q[][tail0++] = nex[][now][i];
}
}
while(head1 != tail1) {
int now = q[][head1++];
sum[][now] |= sum[][fail[][now]];
for(int i = ; i < ; ++i) {
int p = fail[][now];
if(!nex[][now][i]) {
nex[][now][i] = nex[][p][i];continue;
}
fail[][nex[][now][i]] = nex[][p][i];
q[][tail1++] = nex[][now][i];
}
}
}
int len[N],mx,n,L;
char a[N];
int dfs() {
int now = ;
int ret = ;
for(int i = ; i <= *mx; ++i) {
now = nex[][now][len[i]];
ret |= sum[][now];
}
return ret;
}
int ma(int p) {
int now = ;
if(p)
for(int i = mx; i >= ; --i)
now = nex[][now][len[i]];
else
for(int i = mx+; i <= *mx; ++i)
now = nex[][now][len[i]];
return now;
}
void init() {
memset(dp,,sizeof(dp));
memset(nex,,sizeof(nex));
cnt0 = ;mx = -;cnt1 = ;
memset(fail,,sizeof(fail));
memset(sum,,sizeof(sum));
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&L);
init();
for(int i = ; i <= n; ++i) {
scanf("%s",a);
insert(a,i-);
mx = max(mx,(int)strlen(a));
}
int ff = ;
mx-=;
build_fail();
for(int i = ; i < (<<mx); ++i) {
for(int j = ; j <= mx; ++j) len[j] = ((i>>(j-))&);
for(int j = mx+; j <= *mx; ++j) len[j] = ^(len[*mx - j + ]);
int now = dfs();
int z = ma(),f = ma();
dp[ff][z][f][now] += ;
dp[ff][z][f][now] %= mod;
// cout<<i<<" "<<now<<" "<<z<<" "<<f<<endl;
} for(int i = mx; i < L; i++) {
memset(dp[ff^],,sizeof(dp[ff^]));
for(int j = ; j < tail1; ++j) {
for(int k = ; k < tail0; ++k) {
for(int h = ; h < (<<n); ++h) { if(!dp[ff][q[][j]][q[][k]][h]) continue; int p = nex[][q[][j]][],np = nex[][q[][k]][];
int tmp = (h|sum[][p]);
tmp |= sum[][np]; dp[ff^][p][np][tmp] += dp[ff][q[][j]][q[][k]][h];
dp[ff^][p][np][tmp] %= mod; p = nex[][q[][j]][],np = nex[][q[][k]][];
tmp = (h|sum[][p]);
tmp |= sum[][np]; dp[ff^][p][np][tmp] += dp[ff][q[][j]][q[][k]][h];
dp[ff^][p][np][tmp] %= mod; }
}
}
ff^=;
}
LL ans = ;
for(int i = ; i < tail1; ++i)
for(int j = ; j < tail0; ++j)
ans = ( ans + dp[ff][q[][i]][q[][j]][(<<n)-]) % mod;
printf("%lld\n",ans);
}
return ;
}

HDU 6086 Rikka with String AC自动机 + DP的更多相关文章

  1. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  2. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  3. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  4. HDU 6086 Rikka with String ——(AC自动机 + DP)

    这是一个AC自动机+dp的问题,在中间的串的处理可以枚举中断点来插入自动机内来实现,具体参见代码. 在这题上不止为何一直MLE,一直找不到结果(lyf相同写法的代码消耗内存较少),还好考虑到这题节点应 ...

  5. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU 6086 Rikka with String

    Rikka with String http://acm.hdu.edu.cn/showproblem.php?pid=6086 题意: 求一个长度为2L的,包含所给定的n的串,并且满足非对称. 分析 ...

  7. HDU 4758 Walk Through Squares(AC自动机+DP)

    题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...

  8. HDU 2825 Wireless Password【AC自动机+DP】

    给m个单词,由这m个单词组成的一个新单词(两个单词可以重叠包含)长度为n,且新单词中包含的基本单词数目不少于k个.问这样的新单词共有多少个? m很小,用二进制表示新单词中包含基本单词的情况. 用m个单 ...

  9. HDU 4057 Rescue the Rabbit(AC自动机+DP)

    题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...

随机推荐

  1. rabbitmq php扩展amqp安装

    configure: error: Please reinstall the librabbitmq distribution itself or (re)install librabbitmq de ...

  2. LINUX DNS客户端 解析域名慢的问题。

    Linux系统下域名解析的配置文件是/etc/resolv.conf cat /etc/resolv.conf # Generated by NetworkManager options single ...

  3. 【leetcode最短路】818. Race Car

    https://leetcode.com/problems/race-car/description/ 1. BFS剪枝 0<=current position<=2*target.为什么 ...

  4. 转载:LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    原文地址:http://yacare.iteye.com/blog/2010049 很多伙伴在更新VS2010,或者卸载VS2012安装2010后,建立Win32 Console Project/MF ...

  5. CSS选择器与XPath语言

    一 在爬取页面信息的过程中,需要到想要的信息进行定位,主要有两种方法.CSS选择器和XPath语言.查找某一个标签,两种方法都可以做到. 二 CSS选择器 http://www.w3school.co ...

  6. 棋盘制作 BZOJ 1057

    棋盘制作 [问题描述] 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴 ...

  7. hdu 5288 ZCC loves straight flush

    传送门 ZCC loves straight flush Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K ...

  8. Mysql安装及自动化部署脚本方案

    一.简介 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文件中,但是 ...

  9. 利用jquery实现向左滚动效果及offset的使用

    昨天和今天做了一个轮播图,它的tab标签不是1,2,3这样的数据表示,而是使用圆圈表示,效果如下:

  10. SPOJ - PERMJUMP Permutation Jumping

    Discription John likes playing the game Permutation Jumping. First he writes down a permutation A of ...