HDU 6086 Rikka with String AC自动机 + DP
Rikka with String
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.
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).
2 2
011
001
2 3
011
001
4
#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的更多相关文章
- hdu 6086 -- Rikka with String(AC自动机 + 状压DP)
题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...
- 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 ...
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- HDU 6086 Rikka with String ——(AC自动机 + DP)
这是一个AC自动机+dp的问题,在中间的串的处理可以枚举中断点来插入自动机内来实现,具体参见代码. 在这题上不止为何一直MLE,一直找不到结果(lyf相同写法的代码消耗内存较少),还好考虑到这题节点应 ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 6086 Rikka with String
Rikka with String http://acm.hdu.edu.cn/showproblem.php?pid=6086 题意: 求一个长度为2L的,包含所给定的n的串,并且满足非对称. 分析 ...
- HDU 4758 Walk Through Squares(AC自动机+DP)
题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...
- HDU 2825 Wireless Password【AC自动机+DP】
给m个单词,由这m个单词组成的一个新单词(两个单词可以重叠包含)长度为n,且新单词中包含的基本单词数目不少于k个.问这样的新单词共有多少个? m很小,用二进制表示新单词中包含基本单词的情况. 用m个单 ...
- HDU 4057 Rescue the Rabbit(AC自动机+DP)
题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...
随机推荐
- 【UML】关联、依赖、泛化、实现等关系说明
导读:再上一篇博客中,介绍了UML的9种图,现在,将对UML中的关系进行总结.图很重要,但图形中的各种关系也很重要,这扯关系的事儿,从来都是大事儿. 一.基本定义 1.1 总体说明 1.2 具体定义 ...
- RR隔离级别下通过next-key locks 避免幻影读
---恢复内容开始--- mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读 READ COMMITED 不可重复读 在同一事务中两次查看的结果集不 ...
- 【Luogu】P2894酒店Hotel(线段树)
题目链接 我好蒻啊 题题看题解 线段树维护从左端点开始的最长连续空房.右端点结束的最长连续空房.整段区间的最长连续空房.区间非空房的个数. http://blog.csdn.net/qq_3955 ...
- SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树
[题目分析] 问题放到了树上,直接链剖+线段树搞一搞. 调了300行+. (还是码力不够) [代码] #include <cstdio> #include <cstring> ...
- POJ 3469 Dual Core CPU ——网络流
[题目分析] 构造一个最小割的模型. S向每一个点连Ai,每一个点向T连Bi. 对于每一个限制条件,在i和j之间连一条Cij的双向边即可. 然后求出最小割就是最少的花费. 验证最小割的合理性很容易. ...
- 通过new ClasspathApplicationContext("applicationContext.xml")找不到文件时
可以把applicationContext.xml放到/WEB-INF/classes目录下使用先说:ClassPathXmlApplicationContext 这个类,默认获取的是WEB-INF/ ...
- 洛谷 [P1290] 欧几里得的游戏
SG函数的应用 看到这题就想到了SG函数 那么可以考虑最终情况:一个数是x,另一个是0,那么先手必败(因为上一个人已经得到0了,其实游戏已经结束了) 剩下的情况:一个数n, 一个数m,假设n>m ...
- 使用 ftrace 调试 Linux 内核,第 3 部分
内核头文件 include/linux/kernel.h 中描述了 ftrace 提供的工具函数的原型,这些函数包括 trace_printk.tracing_on/tracing_off 等.本文通 ...
- Python 和 Elasticsearch 构建简易搜索
Python 和 Elasticsearch 构建简易搜索 作者:白宁超 2019年5月24日17:22:41 导读:件开发最大的麻烦事之一就是环境配置,操作系统设置,各种库和组件的安装.只有它们都正 ...
- T3187 队列练习3 codevs
http://codevs.cn/problem/3187/ 题目描述 Description 比起第一题,本题加了另外一个操作,访问队头元素(编号3,保证访问队头元素时或出队时队不为空),现在给出这 ...