Description

给定k个长度不超过L的01串,求有多少长度为n的01串S满足:

1.该串是回文串

2.该串不存在两个不重叠的子串,在给定的k个串中。

即不存在a<=b<c<=d,S[a,b]是k个串中的一个,S[c,d]是k个串中的一个

(It does not contain two non-overlapped substrings in the given list of K binary strings.)

举个例子,若给定2(k=2)个01串:101和1001

1010001和1010101均不满足条件。前者不满足条件1,后者不满足条件2

Input

第一行两个整数n,k

以下k行,每行一个01串

Output

输出一个整数表示答案,答案mod 1000000007(10^9+7)
对原串和反串分别建ac自动机,从两边向中间处理回文串,同时在自动机上走,若匹配到一个串就记录并回到起点
dp状态表示为 当前已确定前缀、后缀在ac自动机上的位置,以及是否已匹配到一个串 的方案数
最后检查是否在跨过中点的位置匹配到一个串
#include<cstdio>
#include<cstring>
#include<algorithm>
const int P=1e9+;
int n,k,ls[];
char s[][];
inline void inc(int&a,int b){
b+=a-P;
a=b+(b>>&P);
}
struct acam{
int ch[][],fa[];
int S[][];
bool e[];
int ptr;
acam(){
memset(this,,sizeof(acam));
ptr=;
ch[][]=ch[][]=;
}
void ins(char*s,int a){
int w=;
for(int i=;s[i];++i){
int c=s[i]-'',&u=ch[w][c];
if(!u)u=++ptr;
w=u;
S[w][a]|=<<i;
}
e[w]=;
}
void ins(char*s,int a,int len){
int w=;
for(int i=len-;i>=;--i){
int c=s[i]-'',&u=ch[w][c];
if(!u)u=++ptr;
w=u;
S[w][a]|=<<i;
}
e[w]=;
}
void build(){
int q[],ql=,qr=;
q[++qr]=;
while(ql!=qr){
int w=q[++ql];
for(int i=;i<;++i){
int&u=ch[w][i];
(u?fa[q[++qr]=u]:u)=ch[fa[w]][i];
}
}
for(int i=;i<=qr;++i){
int w=q[i],f=fa[w];
e[w]|=e[f];
for(int j=;j<k;++j)S[w][j]|=S[f][j];
}
}
}t1,t2;
int f[][][][];
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<k;++i){
scanf("%s",s[i]);
ls[i]=strlen(s[i]);
t1.ins(s[i],i);
t2.ins(s[i],i,ls[i]);
}
t1.build();
t2.build();
int now=;
f[][][][]=;
for(int t=;t<n/;++t,now^=){
memset(f[now^],,sizeof(f[][])*(t1.ptr+));
for(int c=;c<;++c){
for(int a=;a<=t1.ptr;++a)if(!t1.e[a]){
int a1=t1.ch[a][c],is=;
if(t1.e[a1])a1=,is=;
int(*f1a)[]=f[now^][a1];
int(*f0a)[]=f[now][a];
for(int b=;b<=t2.ptr;++b)if(!t2.e[b]){
int b1=t2.ch[b][c];
int v=is;
if(t2.e[b1])b1=,++v;
for(int x=;x+v<;++x){
inc(f1a[b1][x+v],f0a[b][x]);
}
}
}
}
}
if(n&){
memset(f[now^],,sizeof(f[][])*(t1.ptr+));
for(int c=;c<;++c){
for(int a=;a<=t1.ptr;++a)if(!t1.e[a]){
int a1=t1.ch[a][c],is=;
if(t1.e[a1])a1=,is=;
int(*f1a)[]=f[now^][a1];
int(*f0a)[]=f[now][a];
for(int b=;b<=t2.ptr;++b)if(!t2.e[b]){
int v=is;
for(int x=;x+v<;++x){
inc(f1a[b][x+v],f0a[b][x]);
}
}
}
}
now^=;
}
int ans=;
for(int a=;a<=t1.ptr;++a){
for(int b=;b<=t2.ptr;++b){
inc(ans,f[now][a][b][]);
for(int c=;c<k;++c)if(t1.S[a][c]<<&t2.S[b][c])goto o;
inc(ans,f[now][a][b][]);
o:;
}
}
printf("%d\n",ans);
return ;
}

bzoj 3768: spoj 4660 Binary palindrome二进制回文串的更多相关文章

  1. [LeetCode] Shortest Palindrome 最短回文串

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  2. lintcode :Valid Palindrome 有效回文串

    题目: 有效回文串 给定一个字符串,判断其是否为一个回文串.只包含字母和数字,忽略大小写. 样例 "A man, a plan, a canal: Panama" 是一个回文. & ...

  3. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

  4. [leetcode]125. Valid Palindrome判断回文串

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  5. [LeetCode] 214. Shortest Palindrome 最短回文串

    Given a string s, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  6. poj 3280 Cheapest Palindrome ---(DP 回文串)

    题目链接:http://poj.org/problem?id=3280 思路: dp[i][j] :=第i个字符到第j个字符之间形成回文串的最小费用. dp[i][j]=min(dp[i+1][j]+ ...

  7. poj3280 Cheapest Palindrome(回文串区间dp)

    https://vjudge.net/problem/POJ-3280 猛刷简单dp第一天第三题. 这个据说是[求字符串通过增减操作变成回文串的最小改动次数]的变体. 首先增减操作的实质是一样的,所以 ...

  8. Atcoder CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning 回文串划分

    题目链接 题意 给定一个字符串(长度\(\leq 2e5\)),将其划分成尽量少的段,使得每段内重新排列后可以成为一个回文串. 题解 分析 每段内重新排列后是一个回文串\(\rightarrow\)该 ...

  9. 214 Shortest Palindrome 最短回文串

    给一个字符串 S, 你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串.例如:给出 "aacecaaa",返回 "aaacecaaa ...

随机推荐

  1. 下拉选择框 Spinner的用法。

    代码如下: package com.lixu.xialakuang; import android.app.Activity; import android.content.Context; impo ...

  2. pyqt5 使用 QTimer, QThread, pyqtSignal 实现自动执行,多线程,自定义信号触发。

    渣渣用法,请等待我心情好的时候更新. 1.第一个例子 1.1 先看mainwindow.py from PyQt5 import QtCore, QtGui, QtWidgets class Ui_M ...

  3. L1-005 考试座位号

    每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位.正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考 ...

  4. bacula配置

    Bacula Bacula是一款开源的跨平台网络备份工具,提供基于企业级的CS的备份解决方案.可以对数据进行备份.恢复.以及完整性校验.  功能特点: 支持完全备份,增量备份,差异备份. 支持多种恢复 ...

  5. MyEclipse移动开发教程:设置所需配置的iOS应用(一)

    MyEclipse个人授权 折扣低至冰点!立即开抢>> [MyEclipse最新版下载] 一.iOS应用程序配置要求 这个进程需要四个需求数据文件: 证书签名请求(CSR)文件 证书签名请 ...

  6. struts2.properties

    #action后缀struts.action.extension=action#上传文件的工作目录与文件的最大尺寸struts.multipart.saveDir=struts.multipart.m ...

  7. ApplicationContext详解以及多个ApplicationContext.xml的相互引用

    如果说BeanFactory是spring的心脏,那么Application就是完整的身躯.ApplicationContext就是由BeanFactory派生出来的. 一.ApplicationCo ...

  8. sprintf 函数

    //$tick 保留{$decimalplaces}位小数,不够位数的小数点后面用0 填充$tick = sprintf( "%.0${decimalplaces}lf ", $i ...

  9. 怎么在windows7下搭建服务器

    怎么在windows7系统安装IIS 图文教程 http://jingyan.baidu.com/article/1e5468f92f6e05484961b703.html 以下本人为列:第一步:先按 ...

  10. magento建立多语言网站

    默认Magento仅仅有English语言包,所以如果想也显示中文,就要安装中文语言包. 步骤: 1. 首先,去http://www.magentocommerce.com/langs/list/下载 ...