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. [luoguP2051] [AHOI2009]中国象棋(DP)

    传送门 注释写明了一切 #include <cstdio> #define N 111 #define p 9999973 #define LL long long int n, m; L ...

  2. Codeforces Round #345 (Div. 2) E. Table Compression(并查集)

    传送门 首先先从小到大排序,如果没有重复的元素,直接一个一个往上填即可,每一个数就等于当前行和列的最大值 + 1 如果某一行或列上有重复的元素,就用并查集把他们连起来,很(不)显然,处于同一行或列的相 ...

  3. 货车运输(codevs 3287)

    题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过 ...

  4. 强大的stringstream

    [本文来自]http://www.builder.com.cn/2003/0304/83250.shtmlhttp://www.cppblog.com/alantop/archive/2007/07/ ...

  5. 使用MYSQL命令直接导入导出SQL文件(转)

    参考:http://blog.csdn.net/jiary5201314/article/details/52026816 1.MYSQL中将数据库导出成SQL文件 其实很简单的,就是一条语句就可以了 ...

  6. GridView动态删除Item

    activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  7. AC日记——A+B Problem(再升级) 洛谷 P1832

    题目背景 ·题目名称是吸引你点进来的 ·实际上该题还是很水的 题目描述 ·1+1=? 显然是2 ·a+b=? 1001回看不谢 ·哥德巴赫猜想 似乎已呈泛滥趋势 ·以上纯属个人吐槽 ·给定一个正整数n ...

  8. vue搭建cli脚手架环境(出现问题及解决,主要是node版本低)

    Vue 提供了一个官方的cli,为单页面应用 (SPA) 快速搭建繁杂的脚手架. 一.vue cli脚手架 脚手架通过webpack搭建开发环境 使用ES6语法 打包压缩js为一个文件 项目文件在环境 ...

  9. java基础之IO流(一)字节流

    java基础之IO流(一)之字节流 IO流体系太大,涉及到的各种流对象,我觉得很有必要总结一下. 那什么是IO流,IO代表Input.Output,而流就是原始数据源与目标媒介的数据传输的一种抽象.典 ...

  10. Spring启动流程

    首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境: 其次,在web.xm ...