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 ...
随机推荐
- Mac 安装、卸载JDK 1.6
卸载 输入 sudo rm -fr /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin sudo rm -fr /Library/Preferenc ...
- python的基本用法(四)文件操作使用
#读文件,文件必须存在才能读f=open('操作文件',encoding='utf-8')res =f.read()print(res)f.close()#写文件fw=open('操作文件',mode ...
- Android后台监控指定app的输入内容,抢红包,模拟点击原理
Android开启辅助功能之后可以用AccessibilityService 去后台监控指定的app的输入内容,也可以监控到app的动作 以及通知栏的动作, 抢红包其实就根据通知栏出现了红包的通知消息 ...
- est-framework框架的基本组件
rest-framework框架的基本组件 快速实例 Quickstart 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列 ...
- HDU 5521.Meeting 最短路模板题
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- python中for循环的三种遍历方式
#!/usr/bin/env python# -*- coding: utf-8 -*-if __name__ == '__main__': list = ['A', 'B', 'C', 'D'] # ...
- 【转】背后的故事之 - 快乐的Lambda表达式(二)
快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...
- JS基础-分支结构-循环-数组
1.分支结构 1.if结构 语法: if(条件){ 语句块: } 注意: 1.条件尽量是boolean的,如果不是boolean的,以下条件值,会当做f ...
- Python12/25--前端之BOM/DOM
一.DOM 1. 什么是DOM 文档对象模型 Document Object Model 文档对象模型 是表示和操作 HTML和XML文档内容的基础API 文档对象模型,是W3C组织推荐的处理可扩展标 ...
- LOJ-10103(求删去割点后最多的连通分量)
题目链接:传送门 思路: (1)这道题的图可能不连通,所以需要多次Tarjan: (2)设置cut[i]=x数组表示第i个节点被删除后右多少个子图(这个只是在一个图中),如果是根节点就要-1,因为根节 ...