• bzoj 3768: spoj 4660 Binary palindrome二进制回文串


    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+7;
    int n,k,ls[33];
    char s[33][33];
    inline void inc(int&a,int b){
        b+=a-P;
        a=b+(b>>31&P);
    }
    struct acam{
        int ch[907][2],fa[907];
        int S[907][33];
        bool e[907];
        int ptr;
        acam(){
            memset(this,0,sizeof(acam));
            ptr=1;
            ch[0][0]=ch[0][1]=1;
        }
        void ins(char*s,int a){
            int w=1;
            for(int i=0;s[i];++i){
                int c=s[i]-'0',&u=ch[w][c];
                if(!u)u=++ptr;
                w=u;
                S[w][a]|=1<<i;
            }
            e[w]=1;
        }
        void ins(char*s,int a,int len){
            int w=1;
            for(int i=len-1;i>=0;--i){
                int c=s[i]-'0',&u=ch[w][c];
                if(!u)u=++ptr;
                w=u;
                S[w][a]|=1<<i;
            }
            e[w]=1;
        }
        void build(){
            int q[907],ql=0,qr=0;
            q[++qr]=1;
            while(ql!=qr){
                int w=q[++ql];
                for(int i=0;i<2;++i){
                    int&u=ch[w][i];
                    (u?fa[q[++qr]=u]:u)=ch[fa[w]][i];
                }
            }
            for(int i=2;i<=qr;++i){
                int w=q[i],f=fa[w];
                e[w]|=e[f];
                for(int j=0;j<k;++j)S[w][j]|=S[f][j];
            }
        }
    }t1,t2;
    int f[2][907][907][2];
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=0;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=0;
        f[0][1][1][0]=1;
        for(int t=0;t<n/2;++t,now^=1){
            memset(f[now^1],0,sizeof(f[0][0])*(t1.ptr+2));
            for(int c=0;c<2;++c){
                for(int a=1;a<=t1.ptr;++a)if(!t1.e[a]){
                    int a1=t1.ch[a][c],is=0;
                    if(t1.e[a1])a1=1,is=1;
                    int(*f1a)[2]=f[now^1][a1];
                    int(*f0a)[2]=f[now][a];
                    for(int b=1;b<=t2.ptr;++b)if(!t2.e[b]){
                        int b1=t2.ch[b][c];
                        int v=is;
                        if(t2.e[b1])b1=1,++v;
                        for(int x=0;x+v<2;++x){
                            inc(f1a[b1][x+v],f0a[b][x]);
                        }
                    }
                }
            }
        }
        if(n&1){
            memset(f[now^1],0,sizeof(f[0][0])*(t1.ptr+2));
            for(int c=0;c<2;++c){
                for(int a=1;a<=t1.ptr;++a)if(!t1.e[a]){
                    int a1=t1.ch[a][c],is=0;
                    if(t1.e[a1])a1=1,is=1;
                    int(*f1a)[2]=f[now^1][a1];
                    int(*f0a)[2]=f[now][a];
                    for(int b=1;b<=t2.ptr;++b)if(!t2.e[b]){
                        int v=is;
                        for(int x=0;x+v<2;++x){
                            inc(f1a[b][x+v],f0a[b][x]);
                        }
                    }
                }
            }
            now^=1;
        }
        int ans=0;
        for(int a=1;a<=t1.ptr;++a){
            for(int b=1;b<=t2.ptr;++b){
                inc(ans,f[now][a][b][0]);
                for(int c=0;c<k;++c)if(t1.S[a][c]<<1&t2.S[b][c])goto o;
                inc(ans,f[now][a][b][1]);
                o:;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    cookie的用法
    期货:高频日内交易
    开发者的福利 NutUIvscode 智能提示来了
    node_exporter/mysqld_exporter + Prometheus + Grafana 监控搭建
    reset.css
    移动端设备上的页面比例始终是1:1
    stylus
    移动端1px物理边框的css
    移动端解决click事件300毫秒延迟
    使 mysql datetime 精确到毫秒
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7162635.html
Copyright © 2020-2023  润新知