hdu 6086 -- Rikka with String(AC自动机 + 状压DP)
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).
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
const int mod=;
const int N=;
struct Node{
int id;
Node *fail;
Node *son[];
int tag1,tag2;
}node[N];
queue<Node *>q;
int tot;
int dp[][][]; void insert1(string s,int id)
{
int len=s.length();
Node *now=&node[];
for(int i=;i<len;i++)
{
int x=s[i]-'';
if(now->son[x]==NULL) now->son[x]=&node[tot++];
now=now->son[x];
}
now->tag1|=(<<id);
}
void insert2(string s,int id)
{
int len=s.length();
Node *now=&node[];
for(int i=;i<len;i++)
{
int x=s[i]-'';
if(now->son[x]==NULL) now->son[x]=&node[tot++];
now=now->son[x];
}
now->tag2|=(<<id);
}
void init()
{
for(int i=;i<N;i++)
{
node[i].id=i;
node[i].fail=NULL;
node[i].son[]=node[i].son[]=NULL;
node[i].tag1=node[i].tag2=;
}
}
void setFail()
{
Node* root=&node[];
q.push(root);
while(!q.empty())
{
Node* now=q.front(); q.pop();
for(int i=;i<;i++)
{
if(now->son[i])
{
Node* p=now->fail;
while(p && (!(p->son[i]))) p=p->fail;
now->son[i]->fail=(p)?(p->son[i]):(root);
now->son[i]->tag1|=now->son[i]->fail->tag1;
now->son[i]->tag2|=now->son[i]->fail->tag2;
q.push(now->son[i]);
}
else now->son[i]=(now!=root)?now->fail->son[i]:(root);
}
}
}
void print()
{
Node* now=&node[];
queue<Node*>qq;
qq.push(now);
while(!qq.empty())
{
now=qq.front(); qq.pop();
cout<<"Y:"<<now->id<<" ";
for(int i=;i<;i++)
{
if(now->son[i]) qq.push(now->son[i]),cout<<now->son[i]->id<<" ";
else cout<<"NULL"<<" ";
}
cout<<endl;
}
}
int main()
{
///cout << "Hello world!" << endl;
int t; cin>>t;
while(t--)
{
init();
tot=;
int n,L; scanf("%d%d",&n,&L);
for(int i=;i<n;i++)
{
string s; cin>>s;
insert1(s,i);
string t=s;
reverse(t.begin(),t.end());
int len=s.length();
for(int j=;j<len;j++)
t[j]=(char)((t[j]-'')^+'');
insert1(t,i); int mnLen=min(len,L);
for(int j=;j<mnLen;j++)
{
int f=;
for(int l=j,r=j+; l>=&&r<len; l--,r++)
{
if((s[l]^s[r])==) { f=; break; }
}
if(!f) continue;
t=s.substr(,j+);
for(int k=*j+;k<len;k++)
{
t=(char)((s[k]-'')^+'')+t;
}
insert2(t,i);
}
}
///print();
setFail();
memset(dp,,sizeof(dp));
dp[][][]=;
int cn=,stu=(<<n);
for(int i=;i<L;i++)
{
int c=cn^;
memset(dp[c],,sizeof(dp[c]));
for(int j=;j<tot;j++)
{
for(int s=;s<stu;s++)
{
if(!dp[cn][j][s]) continue;
if(i<L-)
for(int k=;k<;k++)
{
int x=node[j].son[k]->id;
int tag=node[x].tag1;
dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;
}
else
for(int k=;k<;k++)
{
int x=node[j].son[k]->id;
int tag=node[x].tag1|node[x].tag2;
dp[c][x][s|tag]=(dp[c][x][s|tag]+dp[cn][j][s])%mod;
}
}
}
cn=c;
}
int ans=;
for(int i=;i<tot;i++)
{
ans=(ans+dp[cn][i][stu-])%mod;
}
printf("%d\n",ans);
}
return ;
}
hdu 6086 -- Rikka with String(AC自动机 + 状压DP)的更多相关文章
- HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解
题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...
- 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 ...
- HDU 2825 Wireless Password(AC自动机 + 状压DP)题解
题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...
- HDU - 2825 Wireless Password (AC自动机+状压DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数. 题解: ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- hdu 4057--Rescue the Rabbit(AC自动机+状压DP)
题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...
- BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】
题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
Time Limit: 10 Seconds Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...
- hdu2825 Wireless Password(AC自动机+状压dp)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
随机推荐
- 【VBA】セールの値は配列に変換方法
方法一 Sub test1() //変数の定義 Dim a() As Integer, iRow As Long, i As Integer //非空白のセールまでの行を取得 iRow = Cells ...
- phpcms的一些问题 乱码,安装
一.乱码:我这的网站出现的乱码情况:后台栏目名乱码,迁站后更新缓存,再更新栏目,内容,前台都乱码. 找了半天原因,经过本地测试,没问题,一上线就出现问题,不同点就是线上的数据库版本是mysql5.5, ...
- FortiGate双链路不同运营商上网配置
1.防火墙端口配置 2.LLB配置
- 【转载】重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor ...
- Js学习(6) 标准库-Array对象
Array是Js的原生对象,同时也是一个构造函数,可以用它生成新的数组 用不用new结果都一样 var arr = new Array(2); // 等同于 var arr = Array(2); 但 ...
- 编辑linux内核与bosybox 时,make menuconfig 出现错误
*** Unable to find the ncurses libraries or the *** required header files. *** 'make menuconfig' req ...
- BZOJ2212或洛谷3521 [POI2011]ROT-Tree Rotations
BZOJ原题链接 洛谷原题链接 线段树合并裸题. 因为交换子树只会对子树内部的逆序对产生影响,所以我们计算交换前的逆序对个数和交换后的个数,取\(\min\)即可. 对每个叶子节点建一棵动态开点线段树 ...
- 201621123002《JAVA程序设计》第五周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口 interface关键字 implements关键字 Comparable abstract Comparator 1.2 ...
- 设计模式学习心得<工厂方法 Factory Method>
概述 意图 业务代码中常常有构造对象的过程,它拥有大量的参数.并且有很多地方需要这对象. 简化对象构造过程. 主要解决 一个类在不同场景的频繁地创建,让不同对象的创建更有语义化,提高代码复用性. 何时 ...
- python_day12_html
目录: 简单web的服务器代码 html简介 html常用标签 一.简单web的服务器代码 1.简单python服务器代码: import socket def main(): sock = sock ...