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. Autorelease 性能测试

    __weak NSString *string_weak_ = nil; - (void)viewDidLoad { [super viewDidLoad]; // 场景 1 NSString *st ...

  2. Objective-C与JavaScript交互的那些事

    http://www.cocoachina.com/ios/20160127/15105.html 最近公司的运营瞎搞了个活动,其活动要服务端提供数据支持,web前端在微信公众账号内作为主要的运营阵地 ...

  3. 【[SCOI2009]迷路】

    大水题一遍 过掉比较繁琐的拆点还是非常开心的 发现每一条边的边权可能不是\(1\),但是边权的范围非常小,同时点数也非常小,只有\(n<=10\),所以我们可以将一个点拆成九个点,之后随便一连边 ...

  4. indexzero/http-server-2-使用

    所以在ethereumjs-vm/examples/run-transactions-simple例子中要怎么使用http-server 1.首先在ethereumjs-vm/examples/run ...

  5. PDF压缩,在线压缩免费

    https://smallpdf.com/ 一个很牛逼的网站 https://zh.wikihow.com/ https://zh.wikihow.com/%E9%A6%96%E9%A1%B5

  6. 用PSCP在Windows和Linux之间相互传输文件

    在Linux服务器之间相互传文件我们常用 scp命令,但是在Linux和Windows之间相互传输就不那么直接了. 使用 Putty的 PSCP 则会简单的多 1. 下载 http://www.chi ...

  7. 编程开发之--Oracle数据库--存储过程和存储函数(2)

    上一小结我们简单介绍了存储过程和存储函数,对存储过程和存储函数有了一个基本的了解,接下来介绍在java程序中如何调用我们创建的存储过程和存储函数 1.在应用程序中调用我们的存储过程 创建一个简单的Ja ...

  8. Swift基础学习笔记 一

    之前学习过一段时间swift,由于目前开发的项目还是用的OC,一段时间不看swift又基本忘干净了,好记性不如烂笔头,还是用博客记录一下自己学的东西吧. 基本数据类型: 1.常量(let)和变量(va ...

  9. 『ACM C++』 PTA 天梯赛练习集L1 | 027-028

    死亡周二,今天去看惊奇队长了!!!真的很佩服国外的后期特效大片技术,要是我们国内也能实现这样的技术能力就好了~ 羡慕max -------------------------------------- ...

  10. mac 装5.6版本mysql 设置密码

    最的mysql在装的时候就可以设置 ,但是低版本的好像不行,需要在装了以后才能设置. mac下,mysql5.7.18连接出错,错误信息为:Access denied for user 'root'@ ...