Rikka with String

http://acm.hdu.edu.cn/showproblem.php?pid=6086

题意:

  求一个长度为2L的,包含所给定的n的串,并且满足非对称。

分析:

  AC自动机+状压dp。

  首先给这个n个串,建立AC自动机。然后去枚举长度为L的一个串,就可以知道另一半了。

  如果给定的串完全存在于左边或者右边,那么直接往AC自动机加入这个串或者取反后的反串。如果是跨越中间,那么暴力的把所有的串,从中间切开,然后判断是否合法,加入到AC自动机上就行,如果长度枚举到了i-1的时候,这些串的状态才有用。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int mod = ;
int ch[][], sta1[], sta2[], fail[], q[], dp[][][];
int Index;
char s[], t[], a[], b[]; void Insert(char *s,int n,int id,bool f) {
int u = ;
for (int i = ; i < n; ++i) {
int c = s[i] - '';
if (!ch[u][c]) ch[u][c] = ++Index;
u = ch[u][c];
}
if (f) sta1[u] |= ( << id);
else sta2[u] |= ( << id);
}
void build() {
int L = , R = ;
for (int i = ; i < ; ++i) if (ch[][i]) q[++R] = ch[][i];
while (L <= R) {
int u = q[L ++];
for (int c = ; c < ; ++c) {
int v = ch[u][c];
if (!v) { ch[u][c] = ch[fail[u]][c]; continue; }
int p = fail[u]; while (p && !ch[p][c]) p = fail[p];
q[++R] = v;
fail[v] = ch[p][c];
sta1[v] |= sta1[fail[v]], sta2[v] |= sta2[fail[v]];
}
}
}
void update(char *s,int n,int id) {
int c1 = , c2 = , f = ;
for (int i = ; i < n - ; ++i) {
c1 = c2 = f = ;
for (int j = i; j >= ; --j) a[c1 ++] = s[j];a[c1] = '\0';
for (int j = i + ; j < n; ++j) b[c2 ++] = s[j]; b[c2] = '\0';
for (int j = ; j < c1 && j < c2; ++j) if (a[j] == b[j]) { f = ; break; }
if (f) continue;
for (int j = c1; j < c2; ++j) a[j] = b[j] == '' ? '' : '';
reverse(a, a + max(c1, c2));
Insert(a, max(c1, c2), id, ); // 长度为max(c1,c2)!!!
}
}
void init() {
memset(dp, , sizeof(dp));
memset(ch, , sizeof(ch));
memset(fail, , sizeof(fail));
memset(sta1, , sizeof(sta1));
memset(sta2, , sizeof(sta2));
}
inline void add(int &x,int y) { x += y; if (x >= mod) x -= mod; }
void solve() {
init();
int n = read(), L = read(), len;
for (int i = ; i < n; ++i) {
scanf("%s", s); len = strlen(s);
Insert(s, len, i, );
for (int j = ; j < len; ++j) t[j] = s[j];
reverse(t, t + len);
for (int j = ; j < len; ++j) t[j] = t[j] == '' ? '' : '';
Insert(t, len, i, );
update(s, len, i);
}
build();
dp[][][] = ;
int All = ( << n) - , now = ;
for (int i = ; i < L; ++i, now ^= )
for (int j = ; j <= Index; ++j)
for (int s = ; s <= All; ++s) {
if (dp[now][j][s] <= ) continue;
for (int c = ; c < ; ++c) {
int nv = ch[j][c], ns = s | sta1[nv];
if (i == L - ) ns |= sta2[nv];
add(dp[now ^ ][nv][ns], dp[now][j][s]);
}
dp[now][j][s] = ;
}
int ans = ;
for (int i = ; i <= Index; ++i) add(ans, dp[now][i][All]);
printf("%d\n",ans % mod);
}
int main() {
for (int T = read(); T --; ) solve();
return ;
}

HDU 6086 Rikka with String的更多相关文章

  1. HDU 6086 Rikka with String AC自动机 + DP

    Rikka with String Problem Description As we know, Rikka is poor at math. Yuta is worrying about this ...

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

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

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

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

  4. hdu.5202.Rikka with string(贪心)

    Rikka with string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  5. HDU 5831 Rikka with Parenthesis II(六花与括号II)

    31 Rikka with Parenthesis II (六花与括号II) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536 ...

  6. HDU 6093 - Rikka with Number | 2017 Multi-University Training Contest 5

    JAVA+大数搞了一遍- - 不是很麻烦- - /* HDU 6093 - Rikka with Number [ 进制转换,康托展开,大数 ] | 2017 Multi-University Tra ...

  7. HDU 5842 Lweb and String(Lweb与字符串)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  8. 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence

    // 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...

  9. hdu 4850 Wow! Such String! 欧拉回路

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4080264.html 题目链接:hdu 4850 Wow! Such String! 欧拉回 ...

随机推荐

  1. 【vue】饿了么项目-页面骨架开发

    1.页面骨架开发 1.1组件拆分 手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没 ...

  2. maven 编译替换占位符

    首先开启资源配置的插件,由此插件替换占位符 <plugin> <groupId>org.apache.maven.plugins</groupId> <art ...

  3. CC2540 OSAL 学习其中原理,以及 给任务 添加 一个事件(定时发送串口消息)

    参考学习大神博客: http://blog.csdn.net/feilusia/article/details/51083953 : http://blog.csdn.net/xiaoleiacmer ...

  4. Mac python3连接mysql

    Mac python3连接mysql 安装方法1: 1.pip3 install --upgrade pip //升级pip版本 2.sudo python3 /Library/Frameworks/ ...

  5. iOS之利用腾讯Bugly程序调试,测试代码bug、卡顿等情况

    1.自己先写一个 Demo 演示一下利用bugly测试崩溃的具体情况. 在ViewController里面实现崩溃代码如下:  运行后 毫无疑问程序报错了! 2.使用到第三方的框架Bugly,官方下载 ...

  6. 使用vue封装一个tab栏切换的左侧导航栏的公共组件

     首先看最终效果图: 1.compent文件夹里添加tab文件夹,里面创建index.vue index.js index.css index.vue内的template部份代码如下:(最新更正:代码 ...

  7. debian系统,启动Wireshark,出现Couldn't run /usr/bin/dumpcap in child process:权限不够

    这是由于当前用户没有权限运行/usr/bin/dumpcap造成的./usr/bin/dumpcap是Wireshark的包捕获引擎. 先用ls命令看一下dumpcap的权限情况:xy@debian- ...

  8. 基于JQ的自定义弹窗组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. node.js的http模块创建基本Web服务器

    首先下载node.js模块.终端执行命令 npm i node -g 引入http核心模块 const http =require('http') 引入文件系统模块 const fs =require ...

  10. 关于UIScrollView无限循环滑动

    在使用某宝或某东购物的时候,我们会在其首页看到一个可以滑动的版块,这个版块的实现就是一个UIScrollView.在我们使用UIScrollView的时候会发现,滑动到最后的时候,UIScrollVi ...